PageRenderTime 1584ms CodeModel.GetById 27ms RepoModel.GetById 1ms app.codeStats 0ms

/tools/lazdatadesktop/dicteditor.pp

https://bitbucket.org/etrusco/lazarus-ide
Pascal | 1045 lines | 824 code | 155 blank | 66 comment | 5 complexity | 463646a5120966de79767e79104af11d MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, MPL-2.0-no-copyleft-exception
  1. {
  2. ***************************************************************************
  3. * *
  4. * This source is free software; you can redistribute it and/or modify *
  5. * it under the terms of the GNU General Public License as published by *
  6. * the Free Software Foundation; either version 2 of the License, or *
  7. * (at your option) any later version. *
  8. * *
  9. * This code is distributed in the hope that it will be useful, but *
  10. * WITHOUT ANY WARRANTY; without even the implied warranty of *
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
  12. * General Public License for more details. *
  13. * *
  14. * A copy of the GNU General Public License is available on the World *
  15. * Wide Web at <http://www.gnu.org/copyleft/gpl.html>. You can also *
  16. * obtain it by writing to the Free Software Foundation, *
  17. * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
  18. * *
  19. ***************************************************************************
  20. }
  21. {$ifdef ver2_2}
  22. {$define onlyoldobjects}
  23. {$endif}
  24. unit dicteditor;
  25. {$mode objfpc}{$H+}
  26. interface
  27. uses
  28. Classes, SysUtils, FileUtil, fpdatadict, Controls, ComCtrls, StdCtrls,
  29. ExtCtrls, Graphics, ImgList, RTTIGrids, LResources, menus, dialogs;
  30. Type
  31. TEditObjectType = (eotUnknown,eotDictionary,
  32. eotTables,eotTable,
  33. eotFields,eotField,
  34. eotConnection,eotTableData,
  35. eotIndexes,eotIndex,
  36. eotSequences,eotSequence,
  37. eotForeignKeys,eotForeignKey,
  38. eotDomains,eotDomain);
  39. Const
  40. SingleObjectTypes = [eotTable,eotDomain,eotSequence,
  41. eotField,eotIndex,eotForeignKey];
  42. Type
  43. { TDataDictEditor }
  44. TDataDictEditor = Class(TTabSheet)
  45. private
  46. FDD: TFPDataDictionary;
  47. FIMgList : TImageList;
  48. FImageOffset: Integer;
  49. FModified: Boolean;
  50. FTV : TTreeView;
  51. FEdit : TPanel;
  52. FSplit : TSplitter;
  53. FAllowDoubleClick : TEditObjectType;
  54. FDDNode,
  55. FTablesNode : TTreeNode;
  56. FMenu : TPopupMenu;
  57. FMINewTable,
  58. FMINewField,
  59. FMINewIndex,
  60. FMINewSequence,
  61. FMINewForeignKey,
  62. FMINewDomain,
  63. FMIDeleteObject: TMenuItem;
  64. {$ifndef onlyoldobjects}
  65. FSequencesNode,
  66. FDomainsNode : TTreeNode;
  67. {$endif}
  68. Function AddNewItemPopup(ObjectType: TEditObjectType; AImageIndex : Integer) : TMenuItem;
  69. procedure CreateGUI;
  70. procedure DoDoubleClick(Sender: TObject);
  71. procedure DoNewObject(Sender: TObject);
  72. procedure DoDeleteObject(Sender: TObject);
  73. function CurrentObjectWithType(AType: TEditObjectType): TObject;
  74. function GetCurrentObject: TPersistent;
  75. Function NewNode (TV : TTreeView;ParentNode : TTreeNode; ACaption : String; AImageIndex : Integer) : TTreeNode;
  76. Procedure SetCaption;
  77. Procedure DoSelectNode(Sender : TObject);
  78. Procedure DoPropertyModified(Sender : TObject);
  79. Procedure ClearEditor;
  80. procedure SetModified(const AValue: Boolean);
  81. procedure UpdateSelectedNode;
  82. Function GetObjectType(Node : TTreeNode): TEditObjectType;
  83. Function CreatePropertyGrid(P : TPersistent) : TTIPropertyGrid;
  84. Function FindNodeWithData(TV : TTreeView; P : Pointer) : TTreeNode;
  85. Function SelectNextNode (ANode : TTreeNode; ADefault: TTreeNode) : TTreeNode;
  86. function GetCurrentObjectType: TEditObjectType;
  87. function GetCurrentField: TDDFieldDef;
  88. function GetCurrentIndex: TDDIndexDef;
  89. function GetCurrentTable: TDDTableDef;
  90. {$ifndef onlyoldobjects}
  91. function GetCurrentSequence: TDDSequenceDef;
  92. function GetCurrentForeignKey : TDDForeignKeyDef;
  93. function GetCurrentDomain : TDDDomainDef;
  94. {$endif}
  95. procedure DoPopup(Sender: TObject);
  96. Procedure DeleteGlobalObject(AObject : TObject);
  97. Procedure DeleteTableObject(AObject : TObject);
  98. procedure SelectGlobalObjectList(AObjectType: TEditObjectType);
  99. procedure SelectTableObjectList(AObjectType: TEditObjectType; ATableDef : TDDTableDef);
  100. Procedure SelectSingleObject(AObject : TPersistent);
  101. procedure GetTableObjectsList(ATabledef: TDDTableDef; AObjectType: TEditObjectType; List: TStrings);
  102. procedure GetGlobalObjectsList(AObjectType: TEditObjectType; List: TStrings);
  103. procedure ShowSubLists(TV: TTreeView; ParentNode: TTreeNode; AObject: TObject);
  104. procedure ShowTableObjectList(TV: TTreeView; ParentNode: TTreeNode; ATableDef: TDDTableDef; AObjectType: TEditObjectType);
  105. procedure ShowGlobalObjectList(TV: TTreeView; ParentNode: TTreeNode; AObjectType: TEditObjectType; AShowSubLists : Boolean = False);
  106. Public
  107. Constructor Create(AOwner : TComponent); override;
  108. Destructor Destroy; override;
  109. // General methods.
  110. Procedure ShowDictionary;
  111. Procedure LoadFromFile(AFileName : String);
  112. Procedure SaveToFile(AFileName : String);
  113. Procedure CreateCode;
  114. // New items.
  115. function NewGlobalObject(AObjectName: String; AObjectType: TEditObjectType): TObject;
  116. function NewTableObject(AObjectName: String; TD: TDDTableDef;AObjectType: TEditObjectType): TObject;
  117. Procedure NewField(AFieldName : String; TD : TDDTableDef);
  118. Procedure NewIndex(AIndexName : String; TD : TDDTableDef);
  119. Procedure NewForeignKey(AKeyName : String; TD : TDDTableDef);
  120. // Delete items
  121. {$ifndef onlyoldobjects}
  122. Procedure DeleteSequence(SD : TDDSequenceDef);
  123. Procedure DeleteDomain(DD : TDDDomainDef);
  124. Procedure DeleteForeignKey(KD : TDDForeignKeyDef);
  125. {$endif onlyoldobjects}
  126. Procedure DeleteTable(TD : TDDTableDef);
  127. Procedure DeleteField(FD : TDDFieldDef);
  128. Procedure DeleteIndex(ID : TDDIndexDef);
  129. Procedure DeleteCurrentObject;
  130. // Properties
  131. Property DataDictionary : TFPDataDictionary Read FDD;
  132. Property Modified : Boolean Read FModified Write SetModified;
  133. Property ImageOffset : Integer Read FImageOffset Write FImageOffset;
  134. Property CurrentObject : TPersistent Read GetCurrentObject;
  135. Property ObjectType : TEditObjectType Read GetCurrentObjectType;
  136. Property CurrentTable : TDDTableDef Read GetCurrentTable;
  137. Property CurrentField : TDDFieldDef Read GetCurrentField;
  138. Property CurrentIndex : TDDIndexDef Read GetCurrentIndex;
  139. {$ifndef onlyoldobjects}
  140. Property CurrentSequence : TDDSequenceDef Read GetCurrentSequence;
  141. Property CurrentDomain : TDDDomainDef Read GetCurrentDomain;
  142. Property CurrentForeignKey : TDDForeignKeyDef Read GetCurrentForeignKey;
  143. {$endif onlyoldobjects}
  144. end;
  145. Const
  146. // Image Index for nodes. Relative to ImageOffset;
  147. // Must match the TObjectType
  148. iiDataDict = 0;
  149. iiTables = 1;
  150. iiTable = 2;
  151. iiFields = 3;
  152. iiField = 4;
  153. iiConnection = 5;
  154. iiTableData = 6;
  155. iiIndexes = 7;
  156. iiIndex = 8;
  157. iiSequences = 9;
  158. iiSequence = 10;
  159. iiForeignkeys = 11;
  160. iiForeignKey = 12;
  161. iiDomains = 13;
  162. iiDomain = 14;
  163. IIMaxObject = IIDomain; // Should be last
  164. iiDelete = iiMaxObject+1;
  165. implementation
  166. uses DB, MemDS, fpcodegenerator, TypInfo, lazdatadeskstr;
  167. Function ObjectTypeName(ObjectType : TEditObjectType) : String;
  168. Var
  169. S : String;
  170. begin
  171. Case ObjectType of
  172. eotTable : S:=STable;
  173. eotField : S:=SField;
  174. eotIndex : S:=SIndex;
  175. eotSequence : S:=SSequence;
  176. eotForeignKey : S:=SForeignKey;
  177. eotDomain : S:=SDomain
  178. else
  179. Raise EDataDict.CreateFmt(SErrUnknownType,[Ord(ObjectType)]);
  180. end;
  181. Result:=S;
  182. end;
  183. Function CreateDatasetFromTabledef(TD : TDDTableDef;AOwner : TComponent = Nil) : TDataset;
  184. Var
  185. MDS : TMemDataset;
  186. I : Integer;
  187. FD : TFieldDef;
  188. FDD : TDDFieldDef;
  189. begin
  190. MDS:=TMemDataset.Create(AOwner);
  191. try
  192. For I:=0 to TD.Fields.Count-1 do
  193. begin
  194. FDD:=TD.Fields[i];
  195. MDS.FieldDefs.Add(FDD.FieldName,FDD.FieldType);
  196. end;
  197. MDS.CreateTable;
  198. MDS.Open;
  199. except
  200. MDS.Free;
  201. Raise;
  202. end;
  203. Result:=MDS;
  204. end;
  205. { TDataDictEditor }
  206. function TDataDictEditor.NewNode(TV : TTreeView;ParentNode: TTreeNode; ACaption: String; AImageIndex : Integer
  207. ): TTreeNode;
  208. begin
  209. Result:=TV.Items.AddChild(ParentNode,ACaption);
  210. If AImageIndex>=0 then
  211. begin
  212. Result.ImageIndex:=FImageOffset+AImageIndex;
  213. Result.SelectedIndex:=Result.ImageIndex;
  214. end;
  215. end;
  216. function TDataDictEditor.GetCurrentObjectType: TEditObjectType;
  217. begin
  218. Result:=GetObjectType(FTV.Selected);
  219. end;
  220. function TDataDictEditor.CurrentObjectWithType(AType : TEditObjectType) : TObject;
  221. Var
  222. N : TTreeNode;
  223. begin
  224. Result:=Nil;
  225. N:=FTV.Selected;
  226. While (N<>Nil) and (GetObjectType(N)<>AType) do
  227. N:=N.Parent;
  228. if (N<>Nil) then
  229. Result:=TObject(N.Data);
  230. end;
  231. function TDataDictEditor.GetCurrentObject: TPersistent;
  232. Var
  233. N : TTreeNode;
  234. begin
  235. Result:=Nil;
  236. N:=FTV.Selected;
  237. While (N<>Nil) and Not (GetObjectType(N) in SingleObjectTypes) do
  238. N:=N.Parent;
  239. If Assigned(N) then
  240. Result:=TPersistent(N.Data);
  241. end;
  242. function TDataDictEditor.GetCurrentField: TDDFieldDef;
  243. begin
  244. Result:=TDDFieldDef(CurrentObjectWithType(eotField));
  245. end;
  246. function TDataDictEditor.GetCurrentIndex: TDDIndexDef;
  247. begin
  248. Result:=TDDIndexDef(CurrentObjectWithType(eotIndex));
  249. end;
  250. function TDataDictEditor.GetCurrentTable: TDDTableDef;
  251. begin
  252. Result:=TDDTableDef(CurrentObjectWithType(eotTable));
  253. end;
  254. {$ifndef onlyoldobjects}
  255. function TDataDictEditor.GetCurrentSequence: TDDSequenceDef;
  256. begin
  257. Result:=TDDSequenceDef(CurrentObjectWithType(eotSequence));
  258. end;
  259. function TDataDictEditor.GetCurrentDomain: TDDDomainDef;
  260. begin
  261. Result:=TDDDomainDef(CurrentObjectWithType(eotDomain));
  262. end;
  263. function TDataDictEditor.GetCurrentForeignKey: TDDForeignKeyDef;
  264. begin
  265. Result:=TDDForeignKeyDef(CurrentObjectWithType(eotForeignKey));
  266. end;
  267. {$endif onlyoldobjects}
  268. procedure TDataDictEditor.DoPopup(Sender: TObject);
  269. Var
  270. B : Boolean;
  271. EOT : TEditObjectType;
  272. begin
  273. // Check availablility of items;
  274. B:=CurrentTable<>Nil;
  275. FMINewField.Enabled:=B;
  276. FMINewIndex.Enabled:=B;
  277. FMINewForeignKey.Enabled:=B;
  278. EOT:=ObjectType;
  279. B:=EOT in SingleObjectTypes;
  280. FMIDeleteObject.Enabled:=B;
  281. If B then
  282. FMIDeleteObject.Caption:=Format(SDeleteObject,[ObjectTypeName(EOT)])
  283. else
  284. FMIDeleteObject.Caption:=Format(SDeleteObject,[SObject]);
  285. end;
  286. Function TDataDictEditor.AddNewItemPopup(ObjectType : TEditObjectType; AImageIndex : Integer) : TMenuItem;
  287. Var
  288. S: String;
  289. begin
  290. Result:=TMenuItem.Create(Self);
  291. Result.Name:='NewItem'+GetEnumName(TypeInfo(TEditObjectType),Ord(ObjectType));
  292. Result.Tag:=Ord(ObjectType);
  293. S:=ObjectTypeName(ObjectType);
  294. Result.Caption:=Format(SNew,[S]);
  295. Result.OnClick:=@DoNewObject;
  296. Result.ImageIndex:=AImageIndex;
  297. FMenu.Items.Add(Result);
  298. end;
  299. constructor TDataDictEditor.Create(AOwner: TComponent);
  300. begin
  301. inherited Create(AOwner);
  302. FDD:=TFPDataDictionary.Create;
  303. CreateGUI;
  304. end;
  305. Procedure TDataDictEditor.CreateGUI;
  306. Const
  307. ImageNames : Array[0..IIMaxObject+1] of string =
  308. ('dddatadict','ddtables','ddtable','ddfields','ddfield',
  309. 'ddtables','ddtabledata','ddindexes','ddindex',
  310. 'ddsequences','ddsequence',
  311. 'ddforeignkeys','ddforeignkey',
  312. 'dddomains','dddomain','dddeleteobject');
  313. Var
  314. P : TPortableNetworkGraphic;
  315. I : Integer;
  316. begin
  317. FEdit:=TPanel.Create(Self);
  318. FEdit.Parent:=Self;
  319. FEdit.Name:='FEdit';
  320. FEdit.Align:=alRight;
  321. FEdit.Caption:='';
  322. FEdit.Width:=200;
  323. FSplit:=TSplitter.Create(Self);
  324. FSplit.Parent:=Self;
  325. FSplit.Align:=alRight;
  326. FTV:=TTreeView.Create(Self);
  327. FTV.Name:='FTV';
  328. FTV.Parent:=Self;
  329. FTV.Align:=alClient;
  330. FTV.OnSelectionChanged:=@DoSelectNode;
  331. FTV.ShowLines:=True;
  332. FMenu:=TPopupMenu.Create(Self);
  333. FMenu.Name:='FMenu';
  334. FMenu.OnPopup:=@DoPopup;
  335. FMINewTable:=AddNewItemPopup(eotTable,iiTable);
  336. FMINewField:=AddNewItemPopup(eotField,iiField);
  337. FMINewIndex:=AddNewItemPopup(eotIndex,iiIndex);
  338. FMINewSequence:=AddNewItemPopup(eotSequence,iiSequence);
  339. FMINewForeignKey:=AddNewItemPopup(eotForeignKey,iiForeignKey);
  340. FMINewDomain:=AddNewItemPopup(eotDomain,iiDomain);
  341. FMIDeleteObject:=TMenuItem.Create(Self);
  342. FMIDeleteObject.Caption:=Format(SDeleteObject,[SObject]);
  343. FMIDeleteObject.OnClick:=@DoDeleteObject;
  344. FMIDeleteObject.ImageIndex:=IIDelete;
  345. FMenu.Items.Add(FMIDeleteObject);
  346. FTV.PopupMenu:=FMenu;
  347. FIMgList:=TImageList.Create(Self);
  348. For I:=0 to IIMaxObject+1 do
  349. begin
  350. P:=TPortableNetworkGraphic.Create;
  351. try
  352. P.LoadFromLazarusResource(ImageNames[i]);
  353. FImgList.Add(P,Nil);
  354. finally
  355. P.Free;
  356. end;
  357. end;
  358. FTV.Images:=FImgList;
  359. FMenu.Images:=FImgList;
  360. ShowDictionary;
  361. end;
  362. destructor TDataDictEditor.Destroy;
  363. begin
  364. FreeAndNil(FTV);
  365. FreeAndNil(FDD);
  366. inherited Destroy;
  367. end;
  368. procedure TDataDictEditor.ShowDictionary;
  369. var
  370. S : String;
  371. begin
  372. FTV.Items.BeginUpdate;
  373. try
  374. FTV.Items.Clear;
  375. S:=FDD.Name;
  376. If (S='') then
  377. S:=SNodeDataDictionary;
  378. FDDNode:=NewNode(FTV,Nil,S,iiDataDict);
  379. FDDNode.Data:=FDD;
  380. FTablesNode:=NewNode(FTV,FDDNode,SNodeTables,iiTables);
  381. ShowGlobalObjectList(FTV,FTablesNode,eotTable,True);
  382. {$ifndef onlyoldobjects}
  383. FSequencesNode:=NewNode(FTV,FDDNode,SNodeSequences,iiSequences);
  384. ShowGlobalObjectList(FTV,FSequencesNode,eotSequence,True);
  385. FDomainsNode:=NewNode(FTV,FDDNode,SNodeDomains,iiDomains);
  386. ShowGlobalObjectList(FTV,FDomainsNode,eotDomain,True);
  387. {$endif onlyoldobjects}
  388. SetCaption;
  389. FTV.Selected:=FDDNode;
  390. finally
  391. FTV.Items.EndUpdate;
  392. end;
  393. end;
  394. Function TDataDictEditor.NewGlobalObject(AObjectName: String; AObjectType : TEditObjectType) : TObject;
  395. Var
  396. II : Integer;
  397. N,PN : TTreeNode;
  398. begin
  399. Case AObjectType of
  400. eotTable :
  401. begin
  402. Result:=FDD.Tables.AddTable(AObjectName);
  403. II:=IITable;
  404. PN:=FTablesNode;
  405. end;
  406. {$ifndef onlyoldobjects}
  407. eotSequence :
  408. begin
  409. Result:=FDD.Sequences.AddSequence(AObjectName);
  410. II:=IISequence;
  411. PN:=FSequencesNode;
  412. end;
  413. eotDomain :
  414. begin
  415. Result:=FDD.Domains.AddDomain(AObjectName);
  416. II:=IIDomain;
  417. PN:=FDomainsNode;
  418. end;
  419. {$endif onlyoldobjects}
  420. end;
  421. N:=NewNode(FTV,PN,AObjectName,II);
  422. N.Data:=Result;
  423. FTV.Selected:=N;
  424. ShowSubLists(FTV,N,Result);
  425. Modified:=True;
  426. end;
  427. Function TDataDictEditor.NewTableObject(AObjectName: String; TD: TDDTableDef; AObjectType : TEditObjectType) : TObject;
  428. Var
  429. TN : TTreeNode;
  430. FD : TDDFieldDef;
  431. POT : TEditObjectType;
  432. II : Integer;
  433. begin
  434. Case AObjectType of
  435. eotField :
  436. begin
  437. POT:=eotFields;
  438. Result:=TD.Fields.AddField(AObjectName);
  439. II:=IIfield;
  440. end;
  441. {$ifndef onlyoldobjects}
  442. eotIndex:
  443. begin
  444. POT:=eotIndexes;
  445. Result:=TD.Indexes.AddIndex(AObjectName);
  446. II:=IIIndex;
  447. end;
  448. eotForeignKey :
  449. begin
  450. POT:=eotForeignKeys;
  451. Result:=TD.foreignKeys.AddForeignKeyDef(AObjectName);
  452. II:=IIForeignkey;
  453. end;
  454. {$endif onlyoldobjects}
  455. end;
  456. TN:=FindNodeWithData(FTV,TD);
  457. TN:=TN.GetFirstChild;
  458. While (TN<>Nil) and (GetObjectType(TN)<>POT) do
  459. TN:=TN.GetNextSibling;
  460. If (TN<>Nil) then
  461. begin
  462. TN:=NewNode(FTV,TN,AObjectName,II);
  463. TN.Data:=Result;
  464. FTV.Selected:=TN;
  465. Modified:=True;
  466. end
  467. else
  468. FreeAndNil(Result); // Error !!
  469. end;
  470. procedure TDataDictEditor.NewField(AFieldName: String; TD: TDDTableDef);
  471. begin
  472. NewTableObject(AFieldName,TD,eotField);
  473. end;
  474. procedure TDataDictEditor.NewIndex(AIndexName: String; TD: TDDTableDef);
  475. begin
  476. NewTableObject(AIndexName,TD,eotIndex);
  477. end;
  478. procedure TDataDictEditor.NewForeignKey(AKeyName: String; TD: TDDTableDef);
  479. begin
  480. NewTableObject(AKeyName,TD,eotForeignKey);
  481. end;
  482. procedure TDataDictEditor.SetCaption;
  483. Var
  484. S : String;
  485. begin
  486. If (FDD.Name<>'') then
  487. S:=FDD.Name
  488. else
  489. S:=ChangeFileExt(ExtractFileName(FDD.FileName),'');
  490. If (S='') then
  491. S:=SNewDictionary;
  492. if FModified then
  493. S:=S+' *';
  494. Caption:=S;
  495. end;
  496. procedure TDataDictEditor.DoSelectNode(Sender: TObject);
  497. Var
  498. N : TTreeNode;
  499. O,OP : TObject;
  500. begin
  501. N:=FTV.Selected;
  502. If N=Nil then
  503. exit;
  504. O:=TObject(N.Data);
  505. If Assigned(N.Parent) then
  506. OP:=TObject(N.Parent.Data);
  507. Case ObjectType of
  508. eotUnknown : ;
  509. eotDictionary : SelectSingleObject(FDD);
  510. eotTables : SelectGlobalObjectList(eotTable);
  511. eotTable : SelectSingleObject(O as TPersistent);
  512. eotFields : SelectTableObjectList(eotField,OP as TDDTableDef);
  513. eotField : SelectSingleObject(O as TPersistent);
  514. {$ifndef onlyoldobjects}
  515. eotIndexes : SelectTableObjectList(eotIndex,OP as TDDTableDef);
  516. eotIndex : SelectSingleObject(O as TPersistent);
  517. eotDomains : SelectGlobalObjectList(eotDomain);
  518. eotDomain : SelectSingleObject(O as TPersistent);
  519. eotSequences : SelectGlobalObjectList(eotSequence);
  520. eotSequence : SelectSingleObject(O as TPersistent);
  521. eotForeignKeys : SelectTableObjectList(eotForeignKey,OP as TDDTableDef);
  522. eotForeignKey : SelectSingleObject(O as TPersistent);
  523. {$endif onlyoldobjects}
  524. end;
  525. end;
  526. procedure TDataDictEditor.DoPropertyModified(Sender: TObject);
  527. begin
  528. Modified:=True;
  529. UpdateSelectedNode;
  530. end;
  531. procedure TDataDictEditor.UpdateSelectedNode;
  532. Var
  533. N : TTreeNode;
  534. begin
  535. N:=FTV.Selected;
  536. If (N.Data=Nil) then
  537. Exit;
  538. With N do
  539. Case ObjectType of
  540. eotField : Text:=TDDFieldDef(N.Data).FieldName;
  541. eotDictionary : Text:=TFPDataDictionary(N.Data).Name;
  542. eotTable : Text:=TDDTableDef(N.Data).TableName;
  543. {$ifndef onlyoldobjects}
  544. eotSequence : Text:=TDDSequenceDef(N.Data).SequenceName;
  545. eotDomain : Text:=TDDDomainDef(N.Data).DomainName;
  546. eotForeignKey : Text:=TDDForeignkeyDef(N.Data).KeyName;
  547. {$endif onlyoldobjects}
  548. end;
  549. end;
  550. procedure TDataDictEditor.SelectGlobalObjectList(AObjectType : TEditObjectType);
  551. Var
  552. TV : TTreeView;
  553. begin
  554. ClearEditor;
  555. TV:=TTreeView.Create(Self);
  556. TV.ShowLines:=True;
  557. TV.Parent:=FEdit;
  558. TV.Align:=alClient;
  559. ShowGlobalObjectList(TV,Nil,AObjectType,False);
  560. TV.OnDblClick:=@DoDoubleClick;
  561. FAllowDoubleClick:=AObjectType;
  562. end;
  563. procedure TDataDictEditor.SelectTableObjectList(AObjectType: TEditObjectType; ATableDef : TDDTableDef);
  564. Var
  565. TV : TTreeView;
  566. begin
  567. ClearEditor;
  568. TV:=TTreeView.Create(Self);
  569. TV.ShowLines:=True;
  570. TV.Parent:=FEdit;
  571. TV.Align:=alClient;
  572. ShowTableObjectList(TV,Nil,ATableDef,AObjectType);
  573. TV.OnDblClick:=@DoDoubleClick;
  574. FAllowDoubleClick:=AObjectType;
  575. end;
  576. procedure TDataDictEditor.DoDoubleClick(Sender : TObject);
  577. Var
  578. TV : TTreeView;
  579. N: TTreeNode;
  580. begin
  581. TV:=Sender As TTreeView;
  582. N:=TV.Selected;
  583. If (GetObjectType(N)=FAllowDoubleClick) and (N.Data<>Nil) then
  584. FTV.Selected:=FindNodeWithData(FTV,N.Data);
  585. end;
  586. procedure TDataDictEditor.DoNewObject(Sender: TObject);
  587. Var
  588. EOT : TEditObjectType;
  589. S,N : String;
  590. begin
  591. EOT:=TEditObjectType((Sender as TMenuItem).Tag);
  592. S:=ObjectTypeName(EOT);
  593. if InputQuery(Format(SNewObject,[S]),Format(SNameFor,[S]),N) then
  594. begin
  595. case EOT of
  596. eotField : NewField(N,CurrentTable);
  597. eotIndex : NewIndex(N,CurrentTable);
  598. eotForeignKey : NewForeignKey(N,CurrentTable);
  599. else
  600. NewGlobalObject(N,EOT);
  601. end;
  602. end;
  603. end;
  604. procedure TDataDictEditor.DoDeleteObject(Sender: TObject);
  605. begin
  606. DeleteCurrentObject;
  607. end;
  608. function TDataDictEditor.SelectNextNode(ANode: TTreeNode; ADefault : TTreeNode): TTreeNode;
  609. Var
  610. NN : TTreeNode;
  611. begin
  612. NN:=ANode.GetNextSibling;
  613. If (NN=Nil) then
  614. begin
  615. NN:=ANode.GetPrevSibling;
  616. If (NN=Nil) then
  617. if Assigned(ADefault) then
  618. NN:=ADefault
  619. else
  620. begin
  621. NN:=Anode.Parent;
  622. If Assigned(NN) then
  623. NN:=NN.Parent;
  624. end;
  625. end;
  626. ANode.Free;
  627. FTV.Selected:=NN;
  628. Result:=NN;
  629. end;
  630. procedure TDataDictEditor.SetModified(const AValue: Boolean);
  631. begin
  632. FModified:=AValue;
  633. SetCaption;
  634. end;
  635. Function TDataDictEditor.FindNodeWithData(TV : TTreeView; P : Pointer) : TTreeNode;
  636. Var
  637. I : Integer;
  638. begin
  639. I:=0;
  640. Result:=Nil;
  641. While (Result=Nil) and (I<TV.Items.Count) do
  642. begin
  643. if (TV.Items[i].Data=P) then
  644. Result:=TV.Items[i];
  645. Inc(i);
  646. end;
  647. end;
  648. procedure TDataDictEditor.ClearEditor;
  649. begin
  650. With FEdit do
  651. While (ControlCount>0) do
  652. Controls[ControlCount-1].Free;
  653. end;
  654. procedure TDataDictEditor.SelectSingleObject(AObject: TPersistent);
  655. begin
  656. ClearEditor;
  657. CreatePropertyGrid(AObject);
  658. end;
  659. Function TDataDictEditor.CreatePropertyGrid(P : TPersistent) : TTIPropertyGrid;
  660. begin
  661. Result:=TTIPropertyGrid.Create(Self);
  662. With Result do
  663. begin
  664. Parent:=FEdit;
  665. Align:=alClient;
  666. TIObject:=P;
  667. OnModified:=@DoPropertyModified;
  668. end;
  669. end;
  670. function TDataDictEditor.GetObjectType(Node: TTreeNode): TEditObjectType;
  671. Var
  672. I : Integer;
  673. begin
  674. Result:=eotUnknown;
  675. If Node<>Nil then
  676. begin
  677. I:=Node.ImageIndex;
  678. I:=I-ImageOffset+1;
  679. If (I>=0) and (I<=Ord(High(TEditObjectType))) then
  680. Result:=TEditObjectType(I);
  681. end;
  682. end;
  683. procedure TDataDictEditor.GetTableObjectsList(ATabledef :TDDTableDef; AObjectType : TEditObjectType; List : TStrings);
  684. Var
  685. I : Integer;
  686. begin
  687. Case AObjectType of
  688. eotField : For I:=0 to ATableDef.Fields.Count-1 do
  689. List.AddObject(ATableDef.Fields[i].FieldName,ATableDef.Fields[i]);
  690. {$ifndef onlyoldobjects}
  691. eotIndex : For I:=0 to ATableDef.Indexes.Count-1 do
  692. List.AddObject(ATableDef.Indexes[i].IndexName,ATableDef.Indexes[i]);
  693. eotForeignKey : For I:=0 to ATableDef.ForeignKeys.Count-1 do
  694. List.AddObject(ATableDef.ForeignKeys[i].KeyName,ATableDef.ForeignKeys[i]);
  695. {$endif onlyoldobjects}
  696. end;
  697. If List is TStringList then
  698. TStringList(List).Sorted:=True;
  699. end;
  700. procedure TDataDictEditor.ShowTableObjectList(TV : TTreeView; ParentNode: TTreeNode; ATableDef: TDDTableDef;AObjectType : TEditObjectType);
  701. Var
  702. TN : TTreeNode;
  703. TL : TStringList;
  704. II, I : Integer;
  705. begin
  706. TL:=TStringList.Create;
  707. Try
  708. Case AObjectType of
  709. eotField : II:=iiField;
  710. {$ifndef onlyoldobjects}
  711. eotIndex : II:=iiIndex;
  712. eotForeignKey : II:=iiForeignKey;
  713. {$endif}
  714. end;
  715. GetTableObjectsList(ATableDef,AObjectType,TL);
  716. For I:=0 to TL.Count-1 do
  717. begin
  718. TN:=NewNode(TV,ParentNode,TL[i],II);
  719. TN.Data:=TL.Objects[i];
  720. end;
  721. If Assigned(ParentNode) then
  722. ParentNode.Expand(False);
  723. Finally
  724. FreeAndNil(TL);
  725. end;
  726. end;
  727. procedure TDataDictEditor.GetGlobalObjectsList(AObjectType: TEditObjectType;
  728. List: TStrings);
  729. Var
  730. I : Integer;
  731. begin
  732. Case AObjectType of
  733. eotTable:
  734. For I:=0 to FDD.Tables.Count-1 do
  735. List.AddObject(FDD.Tables[i].TableName,FDD.Tables[i]);
  736. {$ifndef onlyoldobjects}
  737. eotSequence:
  738. For I:=0 to FDD.Sequences.Count-1 do
  739. List.AddObject(FDD.Sequences[i].SequenceName,FDD.Sequences[i]);
  740. eotDomain:
  741. For I:=0 to FDD.Domains.Count-1 do
  742. List.AddObject(FDD.Domains[i].DomainName,FDD.Domains[i]);
  743. {$endif onlyoldobjects}
  744. end;
  745. If List is TStringList then
  746. TStringList(List).Sorted:=True;
  747. end;
  748. procedure TDataDictEditor.ShowSubLists(TV: TTreeView; ParentNode: TTreeNode; AObject : TObject);
  749. Var
  750. TD : TDDTableDef;
  751. N : TTreeNode;
  752. begin
  753. If AObject is TDDTableDef then
  754. begin
  755. TD:=AObject as TDDTableDef;
  756. N:=NewNode(TV,ParentNode,SNodeFields,iiFields);
  757. ShowTableObjectList(TV,N,TD,eotField);
  758. {$ifndef onlyoldobjects}
  759. N:=NewNode(TV,ParentNode,SNodeIndexes,iiIndexes);
  760. ShowTableObjectList(TV,N,TD,eotIndex);
  761. N:=NewNode(TV,ParentNode,SNodeForeignKeys,iiForeignKeys);
  762. ShowTableObjectList(TV,N,TD,eotForeignKey);
  763. {$endif onlyoldobjects}
  764. end;
  765. end;
  766. procedure TDataDictEditor.ShowGlobalObjectList(TV: TTreeView;
  767. ParentNode: TTreeNode; AObjectType: TEditObjectType; AShowSubLists : Boolean = False);
  768. Var
  769. TN : TTreeNode;
  770. TL : TStringList;
  771. II, I : Integer;
  772. begin
  773. TL:=TStringList.Create;
  774. Try
  775. Case AObjectType of
  776. eotTable : II:=iiTable;
  777. {$ifndef onlyoldobjects}
  778. eotSequence : II:=iiSequence;
  779. eotDomain : II:=iiDomain;
  780. {$endif onlyoldobjects}
  781. end;
  782. GetGlobalObjectsList(AObjectType,TL);
  783. For I:=0 to TL.Count-1 do
  784. begin
  785. TN:=NewNode(TV,ParentNode,TL[i],II);
  786. TN.Data:=TL.Objects[i];
  787. If AShowSubLists then
  788. ShowSubLists(TV,TN,TL.Objects[i]);
  789. end;
  790. If Assigned(ParentNode) then
  791. ParentNode.Expand(False);
  792. Finally
  793. FreeAndNil(TL);
  794. end;
  795. end;
  796. procedure TDataDictEditor.DeleteGlobalObject(AObject: TObject);
  797. Var
  798. N,NN : TTreeNode;
  799. begin
  800. N:=FindNodeWithData(FTV,Pointer(AObject));
  801. NN:=SelectNextNode(N,FDDNode);
  802. AObject.Free;
  803. Modified:=True;
  804. end;
  805. procedure TDataDictEditor.DeleteTableObject(AObject: TObject);
  806. Var
  807. N,NN : TTreeNode;
  808. begin
  809. N:=FindNodeWithData(FTV,Pointer(AObject));
  810. NN:=SelectNextNode(N,Nil);
  811. AObject.Free;
  812. Modified:=True;
  813. end;
  814. procedure TDataDictEditor.LoadFromFile(AFileName: String);
  815. begin
  816. FDD.LoadFromFile(UTF8ToSys(AFileName));
  817. ShowDictionary;
  818. SetCaption;
  819. end;
  820. procedure TDataDictEditor.SaveToFile(AFileName: String);
  821. begin
  822. With FDD do
  823. begin
  824. If (Name='') then
  825. Name:=ChangeFileExt(ExtractFileName(AFileName),'');
  826. SaveToFile(AFileName);
  827. end;
  828. Modified:=False;
  829. end;
  830. procedure TDataDictEditor.DeleteTable(TD: TDDTableDef);
  831. begin
  832. DeleteGlobalObject(TD);
  833. end;
  834. procedure TDataDictEditor.DeleteField(FD: TDDFieldDef);
  835. begin
  836. DeleteTableObject(FD);
  837. end;
  838. procedure TDataDictEditor.DeleteIndex(ID: TDDIndexDef);
  839. begin
  840. DeleteTableObject(ID);
  841. end;
  842. procedure TDataDictEditor.DeleteCurrentObject;
  843. Var
  844. N : TTreeNode;
  845. begin
  846. N:=FTV.Selected;
  847. If GetCurrentObjectType in [eotField,eotIndex,eotForeignKey] then
  848. DeleteTableObject(TObject(N.Data))
  849. else
  850. DeleteGlobalObject(TObject(N.Data))
  851. end;
  852. {$ifndef onlyoldobjects}
  853. procedure TDataDictEditor.DeleteSequence(SD: TDDSequenceDef);
  854. begin
  855. DeleteGlobalObject(SD);
  856. end;
  857. procedure TDataDictEditor.DeleteDomain(DD: TDDDomainDef);
  858. begin
  859. DeleteGlobalObject(DD);
  860. end;
  861. procedure TDataDictEditor.DeleteForeignKey(KD: TDDForeignKeyDef);
  862. begin
  863. DeleteTableObject(KD);
  864. end;
  865. {$endif onlyoldobjects}
  866. procedure TDataDictEditor.CreateCode;
  867. Var
  868. TD : TDDTableDef;
  869. DS : TDataset;
  870. begin
  871. TD:=CurrentTable;
  872. If Not assigned(TD) then
  873. exit;
  874. DS:=CreateDatasetFromTabledef(TD,Self);
  875. try
  876. With TFPCodeGenerator.Create(DS) do
  877. try
  878. DataSet:=DS;
  879. TableNameHint:=TD.TableName;
  880. Execute;
  881. Finally
  882. Free;
  883. end;
  884. finally
  885. DS.Free;
  886. end;
  887. end;
  888. initialization
  889. {$i dicteditor.lrs}
  890. end.