1 { /***************************************************************************
2 codetoolsdefines.pas - Lazarus IDE unit
3 -----------------------------------------
4
5 ***************************************************************************/
6
7 ***************************************************************************
8 * *
9 * This source is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 * This code is distributed in the hope that it will be useful, but *
15 * WITHOUT ANY WARRANTY; without even the implied warranty of *
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
17 * General Public License for more details. *
18 * *
19 * A copy of the GNU General Public License is available on the World *
20 * Wide Web at <http://www.gnu.org/copyleft/gpl.html>. You can also *
21 * obtain it by writing to the Free Software Foundation, *
22 * Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1335, USA. *
23 * *
24 ***************************************************************************
25
26 Author: Mattias Gaertner
27
28 Abstract:
29 - TCodeToolsDefinesEditor is an editor for the CodeTools DefineTree used by
30 the IDE. The DefineTree defines all values, that are not in the sources,
31 but are provided by for example Makefiles, compiler command lines and
32 compiler config files.
33
34 There are three types of nodes:
35 - auto generated: These are created by the IDE.
36 - project specific: These nodes are saved in the project info file (.lpi)
37 - the rest are global nodes, saved in the codetoolsoptions.xml file.
38
39 }
40 unit CodeToolsDefines;
41
42 {$mode objfpc}{$H+}
43
44 interface
45
46 uses
47 Classes, SysUtils, Math,
48 // LCL
49 LCLType, LCLIntf, Forms, Controls, Buttons, StdCtrls,
50 ComCtrls, ExtCtrls, Menus, Graphics, Dialogs, ButtonPanel,
51 // LazUtils
52 LazFileUtils, LazLogger, LazStringUtils,
53 // SynEdit
54 SynEdit,
55 // Codetools
56 CodeToolManager, DefineTemplates,
57 // IdeIntf
58 IDEWindowIntf, IDEImagesIntf, IDEDialogs,
59 // IDE
60 LazarusIDEStrConsts, CodeToolsOptions, CodeToolsDefPreview, TransferMacros,
61 EditorOptions, InputFileDialog, LazConf, IDEProcs, EditDefineTree, CompilerOptions;
62
63 type
64
65 { TCodeToolsDefinesEditor }
66
67 TCodeToolsDefinesEditor = class(TForm)
68 ButtonPanel1: TButtonPanel;
69 MenuItem1: TMenuItem;
70 MenuItem10: TMenuItem;
71 MenuItem11: TMenuItem;
72 MenuItem14: TMenuItem;
73 MenuItem16: TMenuItem;
74 MenuItem17: TMenuItem;
75 MenuItem18: TMenuItem;
76 MenuItem19: TMenuItem;
77 MenuItem23: TMenuItem;
78 MenuItem27: TMenuItem;
79 MenuItem29: TMenuItem;
80 MenuItem3: TMenuItem;
81 MenuItem30: TMenuItem;
82 ValueAsTextPage: TTabSheet;
83 ValueAsPathsPage: TTabSheet;
84 MainSplitter: TSplitter;
85 MainMenu: TMainMenu;
86
87
88 // edit nodes
89 EditMenuItem: TMenuItem;
90 MoveNodeUpMenuItem: TMenuItem;
91 MoveNodeDownMenuItem: TMenuItem;
92 MoveNodeLvlUpMenuItem: TMenuItem;
93 MoveNodeLvlDownMenuItem: TMenuItem;
94 InsertBehindMenuItem: TMenuItem;
95 InsertBehindDefineMenuItem: TMenuItem;
96 InsertBehindDefineRecurseMenuItem: TMenuItem;
97 InsertBehindUndefineMenuItem: TMenuItem;
98 InsertBehindUndefineRecurseMenuItem: TMenuItem;
99 InsertBehindUndefineAllMenuItem: TMenuItem;
100 InsertBehindBlockMenuItem: TMenuItem;
101 InsertBehindDirectoryMenuItem: TMenuItem;
102 InsertBehindIfMenuItem: TMenuItem;
103 InsertBehindIfDefMenuItem: TMenuItem;
104 InsertBehindIfNotDefMenuItem: TMenuItem;
105 InsertBehindElseIfMenuItem: TMenuItem;
106 InsertBehindElseMenuItem: TMenuItem;
107 InsertAsChildMenuItem: TMenuItem;
108 InsertAsChildDefineMenuItem: TMenuItem;
109 InsertAsChildDefineRecurseMenuItem: TMenuItem;
110 InsertAsChildUndefineMenuItem: TMenuItem;
111 InsertAsChildUndefineRecurseMenuItem: TMenuItem;
112 InsertAsChildUndefineAllMenuItem: TMenuItem;
113 InsertAsChildBlockMenuItem: TMenuItem;
114 InsertAsChildDirectoryMenuItem: TMenuItem;
115 InsertAsChildIfMenuItem: TMenuItem;
116 InsertAsChildIfDefMenuItem: TMenuItem;
117 InsertAsChildIfNotDefMenuItem: TMenuItem;
118 InsertAsChildElseIfMenuItem: TMenuItem;
119 InsertAsChildElseMenuItem: TMenuItem;
120 DeleteNodeMenuItem: TMenuItem;
121 ConvertActionMenuItem: TMenuItem;
122 ConvertActionToDefineMenuItem: TMenuItem;
123 ConvertActionToDefineRecurseMenuItem: TMenuItem;
124 ConvertActionToUndefineMenuItem: TMenuItem;
125 ConvertActionToUndefineRecurseMenuItem: TMenuItem;
126 ConvertActionToUndefineAllMenuItem: TMenuItem;
127 ConvertActionToBlockMenuItem: TMenuItem;
128 ConvertActionToDirectoryMenuItem: TMenuItem;
129 ConvertActionToIfMenuItem: TMenuItem;
130 ConvertActionToIfDefMenuItem: TMenuItem;
131 ConvertActionToIfNotDefMenuItem: TMenuItem;
132 ConvertActionToElseIfMenuItem: TMenuItem;
133 ConvertActionToElseMenuItem: TMenuItem;
134 CopyToClipbrdMenuItem: TMenuItem;
135 PasteFromClipbrdMenuItem: TMenuItem;
136
137 // tools
138 ToolsMenuItem: TMenuItem;
139 OpenPreviewMenuItem: TMenuItem;
140 ShowMacroListMenuItem: TMenuItem;
141
142 // templates
143 InsertTemplateMenuItem: TMenuItem;
144 InsertFPCProjectDefinesTemplateMenuItem: TMenuItem;
145 InsertFPCompilerDefinesTemplateMenuItem: TMenuItem;
146 InsertFPCSourceDirTemplateMenuItem: TMenuItem;
147 InsertDelphi5CompilerDefinesTemplateMenuItem: TMenuItem;
148 InsertDelphi5DirectoryTemplateMenuItem: TMenuItem;
149 InsertDelphi5ProjectTemplateMenuItem: TMenuItem;
150 InsertDelphi6CompilerDefinesTemplateMenuItem: TMenuItem;
151 InsertDelphi6DirectoryTemplateMenuItem: TMenuItem;
152 InsertDelphi6ProjectTemplateMenuItem: TMenuItem;
153 InsertDelphi7CompilerDefinesTemplateMenuItem: TMenuItem;
154 InsertDelphi7DirectoryTemplateMenuItem: TMenuItem;
155 InsertDelphi7ProjectTemplateMenuItem: TMenuItem;
156 InsertKylix3CompilerDefinesTemplateMenuItem: TMenuItem;
157 InsertKylix3DirectoryTemplateMenuItem: TMenuItem;
158 InsertKylix3ProjectTemplateMenuItem: TMenuItem;
159
160 // define tree
161 DefineTreeView: TTreeView;
162
163 // selected item
164 SelectedItemGroupBox: TGroupBox;
165 TypeLabel: TLabel;
166 NameLabel: TLabel;
167 NameEdit: TEdit;
168 DescriptionLabel: TLabel;
169 DescriptionEdit: TEdit;
170 VariableLabel: TLabel;
171 VariableEdit: TEdit;
172 ValueNoteBook: TPageControl;
173 ValueAsTextSynEdit: TSynEdit;
174 ValueAsFilePathsSynEdit: TSynEdit;
175 MoveFilePathUpBitBtn: TBitBtn;
176 MoveFilePathDownBitBtn: TBitBtn;
177 DeleteFilePathBitBtn: TBitBtn;
178 InsertFilePathBitBtn: TBitBtn;
179
180 // preview
181 //DefinePreview: TCodeToolsDefinesPreview;
182
183 // misc
184 procedure CodeToolsDefinesEditorKeyDown(Sender: TObject; var Key: Word;
185 Shift: TShiftState);
186 procedure CodeToolsDefinesEditorKeyUp(Sender: TObject; var Key: Word;
187 Shift: TShiftState);
188 procedure DefineTreeViewSelectionChanged(Sender: TObject);
189 procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
190 procedure FormCreate(Sender: TObject);
191 procedure OKButtonClick(Sender: TObject);
192
193 // value notebook
194 procedure ValueNoteBookPageChanged(Sender: TObject);
195 procedure MoveFilePathUpBitBtnClick(Sender: TObject);
196 procedure MoveFilePathDownBitBtnClick(Sender: TObject);
197 procedure DeleteFilePathBitBtnClick(Sender: TObject);
198 procedure InsertFilePathBitBtnClick(Sender: TObject);
199
200 // edit menu
201 procedure InsertNodeMenuItemClick(Sender: TObject);
202 procedure MoveNodeUpMenuItemClick(Sender: TObject);
203 procedure MoveNodeDownMenuItemClick(Sender: TObject);
204 procedure MoveNodeLvlUpMenuItemClick(Sender: TObject);
205 procedure MoveNodeLvlDownMenuItemClick(Sender: TObject);
206 procedure DeleteNodeMenuItemClick(Sender: TObject);
207 procedure ConvertActionMenuItemClick(Sender: TObject);
208
209 // tools menu
210 procedure OpenPreviewMenuItemClick(Sender: TObject);
211
212 // template menu
213 procedure InsertFPCProjectDefinesTemplateMenuItemClick(Sender: TObject);
214 procedure InsertFPCompilerDefinesTemplateMenuItemClick(Sender: TObject);
215 procedure InsertFPCSourceDirDefinesTemplateMenuItemClick(Sender: TObject);
216 procedure InsertDelphiCompilerDefinesTemplateMenuItemClick(Sender: TObject);
217 procedure InsertDelphiDirectoryTemplateMenuItemClick(Sender: TObject);
218 procedure InsertDelphiProjectTemplateMenuItemClick(Sender: TObject);
219 procedure InsertKylixCompilerDefinesTemplateMenuItemClick(Sender: TObject);
220 procedure InsertKylixDirectoryTemplateMenuItemClick(Sender: TObject);
221 procedure InsertKylixProjectTemplateMenuItemClick(Sender: TObject);
222 private
223 FDefineTree: TDefineTree;
224 FLastSelectedNode: TTreeNode;
225 FBoss: TCodeToolManager;
226 FTransferMacros: TTransferMacroList;
227 procedure CreateComponents;
CreateSeperatornull228 function CreateSeperator : TMenuItem;
229 procedure SetTransferMacros(const AValue: TTransferMacroList);
230 procedure ValueAsPathToValueAsText;
231 procedure SaveSelectedValues;
232 procedure ShowSelectedValues;
233 procedure SetTypeLabel;
ValueToFilePathTextnull234 function ValueToFilePathText(const AValue: string): string;
235 procedure InsertNewNode(Behind: boolean; DefAction: TDefineAction);
236 procedure InsertTemplate(NewTemplate: TDefineTemplate);
FindUniqueNamenull237 function FindUniqueName: string;
ConsistencyChecknull238 function ConsistencyCheck: integer;
239 procedure SetValuesEditable(AValue: boolean);
240 public
241 procedure SetOptions(ACodeToolBoss: TCodeToolManager);
242 constructor Create(TheOwner: TComponent); override;
243 destructor Destroy; override;
244 property DefineTree: TDefineTree read FDefineTree;
245 property Boss: TCodeToolManager read FBoss write FBoss;
246 property Macros: TTransferMacroList
247 read FTransferMacros write SetTransferMacros;
248 end;
249
ShowCodeToolsDefinesEditornull250 function ShowCodeToolsDefinesEditor(ACodeToolBoss: TCodeToolManager;
251 Options: TCodeToolsOptions; Macros: TTransferMacroList): TModalResult;
252
253
254 implementation
255
256 {$R *.lfm}
257
ShowCodeToolsDefinesEditornull258 function ShowCodeToolsDefinesEditor(ACodeToolBoss: TCodeToolManager;
259 Options: TCodeToolsOptions; Macros: TTransferMacroList): TModalResult;
260 var CodeToolsDefinesEditor: TCodeToolsDefinesEditor;
261 begin
262 CodeToolsDefinesEditor:=TCodeToolsDefinesEditor.Create(nil);
263 CodeToolsDefinesEditor.SetOptions(ACodeToolBoss);
264 CodeToolsDefinesEditor.Macros:=Macros;
265 Result:=CodeToolsDefinesEditor.ShowModal;
266 if Result=mrOk then begin
267 if not CodeToolsDefinesEditor.DefineTree.IsEqual(ACodeToolBoss.DefineTree)
268 then begin
269 ACodeToolBoss.DefineTree.AssignNonAutoCreated(
270 CodeToolsDefinesEditor.DefineTree);
271 Options.ReadGlobalDefinesTemplatesFromTree(ACodeToolBoss.DefineTree);
272 Options.Save;
273 end;
274 end;
275 CodeToolsDefinesEditor.Free;
276 end;
277
278 { TCodeToolsDefinesEditor }
279
280 procedure TCodeToolsDefinesEditor.CodeToolsDefinesEditorKeyDown(
281 Sender: TObject; var Key: Word; Shift: TShiftState);
282 begin
283 if (Shift=[]) and (Key=VK_ESCAPE) then ModalResult:=mrCancel;
284 end;
285
286 procedure TCodeToolsDefinesEditor.CodeToolsDefinesEditorKeyUp(Sender: TObject;
287 var Key: Word; Shift: TShiftState);
288 begin
289 if (Key=VK_ESCAPE) and (Shift=[]) then
290 ModalResult:=mrCancel;
291 end;
292
293 procedure TCodeToolsDefinesEditor.DefineTreeViewSelectionChanged(Sender: TObject);
294 begin
295 ShowSelectedValues;
296 end;
297
298 procedure TCodeToolsDefinesEditor.FormClose(Sender: TObject;
299 var CloseAction: TCloseAction);
300 begin
301 if CloseAction=caNone then ;
302 CodeToolsOpts.DefinesEditMainSplitterTop:=MainSplitter.Top;
303 CodeToolsOpts.Save;
304 IDEDialogLayoutList.SaveLayout(Self);
305 end;
306
307 procedure TCodeToolsDefinesEditor.FormCreate(Sender: TObject);
308 begin
309 ButtonPanel1.OKButton.Caption:= lisOk;
310 ButtonPanel1.CancelButton.Caption:= lisCancel;
311 end;
312
313 procedure TCodeToolsDefinesEditor.OKButtonClick(Sender: TObject);
314 begin
315 SaveSelectedValues;
316 FLastSelectedNode:=nil;
317 ModalResult:=mrOk;
318 end;
319
320 procedure TCodeToolsDefinesEditor.ValueNoteBookPageChanged(Sender: TObject);
321 begin
322 if ValueNoteBook.PageIndex=0 then
323 ValueAsPathToValueAsText
324 else
325 ValueAsFilePathsSynEdit.Text:=ValueToFilePathText(ValueAsTextSynEdit.Text);
326 end;
327
328 procedure TCodeToolsDefinesEditor.MoveFilePathUpBitBtnClick(Sender: TObject);
329 var y: integer;
330 begin
331 if ValueAsFilePathsSynEdit.ReadOnly then exit;
332 y:=ValueAsFilePathsSynEdit.CaretY-1;
333 if (y>0) and (y<ValueAsFilePathsSynEdit.Lines.Count) then
334 ValueAsFilePathsSynEdit.Lines.Move(y,y-1);
335 end;
336
337 procedure TCodeToolsDefinesEditor.MoveFilePathDownBitBtnClick(Sender: TObject);
338 var y: integer;
339 begin
340 if ValueAsFilePathsSynEdit.ReadOnly then exit;
341 y:=ValueAsFilePathsSynEdit.CaretY-1;
342 if (y>=0) and (y<ValueAsFilePathsSynEdit.Lines.Count-1) then
343 ValueAsFilePathsSynEdit.Lines.Move(y,y+1);
344 end;
345
346 procedure TCodeToolsDefinesEditor.DeleteFilePathBitBtnClick(Sender: TObject);
347 var y: integer;
348 begin
349 if ValueAsFilePathsSynEdit.ReadOnly then exit;
350 y:=ValueAsFilePathsSynEdit.CaretY-1;
351 if (y>=0) and (y<ValueAsFilePathsSynEdit.Lines.Count) then
352 ValueAsFilePathsSynEdit.Lines.Delete(y);
353 end;
354
355 procedure TCodeToolsDefinesEditor.InsertFilePathBitBtnClick(Sender: TObject);
356 var y: integer;
357 begin
358 if ValueAsFilePathsSynEdit.ReadOnly then exit;
359 y:=ValueAsFilePathsSynEdit.CaretY-1;
360 if (y>=0) and (y<ValueAsFilePathsSynEdit.Lines.Count) then
361 ValueAsFilePathsSynEdit.Lines.Insert(y,'');
362 end;
363
364 procedure TCodeToolsDefinesEditor.InsertNodeMenuItemClick(Sender: TObject);
365 var Behind: boolean;
366 DefAction: TDefineAction;
367 begin
368 Behind:=(TMenuItem(Sender).Parent=InsertBehindMenuItem);
369 if Sender=InsertBehindDefineMenuItem then DefAction:=da_Define
370 else if Sender=InsertBehindDefineRecurseMenuItem then DefAction:=da_DefineRecurse
371 else if Sender=InsertBehindUndefineMenuItem then DefAction:=da_Undefine
372 else if Sender=InsertBehindUndefineRecurseMenuItem then DefAction:=da_UndefineRecurse
373 else if Sender=InsertBehindUndefineAllMenuItem then DefAction:=da_UndefineAll
374 else if Sender=InsertBehindBlockMenuItem then DefAction:=da_Block
375 else if Sender=InsertBehindDirectoryMenuItem then DefAction:=da_Directory
376 else if Sender=InsertBehindIfMenuItem then DefAction:=da_If
377 else if Sender=InsertBehindIfDefMenuItem then DefAction:=da_IfDef
378 else if Sender=InsertBehindIfNotDefMenuItem then DefAction:=da_IfNDef
379 else if Sender=InsertBehindElseIfMenuItem then DefAction:=da_ElseIf
380 else if Sender=InsertBehindElseMenuItem then DefAction:=da_Else
381 else if Sender=InsertAsChildDefineMenuItem then DefAction:=da_Define
382 else if Sender=InsertAsChildDefineRecurseMenuItem then DefAction:=da_DefineRecurse
383 else if Sender=InsertAsChildUndefineMenuItem then DefAction:=da_Undefine
384 else if Sender=InsertAsChildUndefineRecurseMenuItem then DefAction:=da_UndefineRecurse
385 else if Sender=InsertAsChildUndefineAllMenuItem then DefAction:=da_UndefineAll
386 else if Sender=InsertAsChildBlockMenuItem then DefAction:=da_Block
387 else if Sender=InsertAsChildDirectoryMenuItem then DefAction:=da_Directory
388 else if Sender=InsertAsChildIfMenuItem then DefAction:=da_If
389 else if Sender=InsertAsChildIfDefMenuItem then DefAction:=da_IfDef
390 else if Sender=InsertAsChildIfNotDefMenuItem then DefAction:=da_IfNDef
391 else if Sender=InsertAsChildElseIfMenuItem then DefAction:=da_ElseIf
392 else if Sender=InsertAsChildElseMenuItem then DefAction:=da_Else
393 else DefAction:=da_None;
394 InsertNewNode(Behind,DefAction);
395 end;
396
397 procedure TCodeToolsDefinesEditor.MoveNodeUpMenuItemClick(Sender: TObject);
398 var
399 SelTreeNode: TTreeNode;
400 SelDefNode, PrevDefNode: TDefineTemplate;
401 begin
402 SelTreeNode:=DefineTreeView.Selected;
403 SaveSelectedValues;
404 if (SelTreeNode=nil) or (SelTreeNode.GetPrevSibling=nil) then exit;
405 SelDefNode:=TDefineTemplate(SelTreeNode.Data);
406 PrevDefNode:=SelDefNode.Prior;
407 // move node up in TreeView
408 SelTreeNode.MoveTo(SelTreeNode.GetPrevSibling,naInsert);
409 // move node up in DefineTree
410 SelDefNode.Unbind;
411 SelDefNode.InsertInFront(PrevDefNode);
412 SelTreeNode.MakeVisible;
413 end;
414
415 procedure TCodeToolsDefinesEditor.MoveNodeDownMenuItemClick(Sender: TObject);
416 var
417 SelTreeNode: TTreeNode;
418 SelDefNode, NextDefNode: TDefineTemplate;
419 begin
420 SelTreeNode:=DefineTreeView.Selected;
421 SaveSelectedValues;
422 if (SelTreeNode=nil) or (SelTreeNode.GetNextSibling=nil) then exit;
423 SelDefNode:=TDefineTemplate(SelTreeNode.Data);
424 NextDefNode:=SelDefNode.Next;
425 // move node down in TreeView
426 if SelTreeNode.GetNextSibling.GetNextSibling<>nil then
427 SelTreeNode.MoveTo(SelTreeNode.GetNextSibling.GetNextSibling,naInsert)
428 else
429 SelTreeNode.MoveTo(SelTreeNode.GetNextSibling,naAdd);
430 // move node down in DefineTree
431 SelDefNode.Unbind;
432 SelDefNode.InsertBehind(NextDefNode);
433 SelTreeNode.MakeVisible;
434 end;
435
436 procedure TCodeToolsDefinesEditor.MoveNodeLvlUpMenuItemClick(Sender: TObject);
437 var
438 SelTreeNode: TTreeNode;
439 SelDefNode, PrevDefNode: TDefineTemplate;
440 begin
441 SelTreeNode:=DefineTreeView.Selected;
442 SaveSelectedValues;
443 if (SelTreeNode=nil) or (SelTreeNode.Parent=nil) then exit;
444 SelDefNode:=TDefineTemplate(SelTreeNode.Data);
445 if SelDefNode.IsAutoGenerated then begin
446 IDEMessageDialog(lisCodeToolsDefsNodeIsReadonly,
447 lisCodeToolsDefsAutoGeneratedNodesCanNotBeEdited,
448 mtInformation,[mbCancel]);
449 exit;
450 end;
451 // move node one lvl up in TreeView
452 if SelTreeNode.Parent.GetNextSibling<>nil then
453 SelTreeNode.MoveTo(SelTreeNode.Parent.GetNextSibling,naInsert)
454 else
455 SelTreeNode.MoveTo(SelTreeNode.Parent,naAdd);
456 // move node one lvl up in DefineTree
457 PrevDefNode:=SelDefNode.Parent;
458 SelDefNode.Unbind;
459 SelDefNode.InsertBehind(PrevDefNode);
460 SetNodeImages(SelTreeNode,true);
461 SelTreeNode.MakeVisible;
462 end;
463
464 procedure TCodeToolsDefinesEditor.MoveNodeLvlDownMenuItemClick(Sender: TObject);
465 var
466 SelTreeNode: TTreeNode;
467 SelDefNode, PrevDefNode: TDefineTemplate;
468 begin
469 SelTreeNode:=DefineTreeView.Selected;
470 SaveSelectedValues;
471 if (SelTreeNode=nil) or (SelTreeNode.GetPrevSibling=nil) then exit;
472 SelDefNode:=TDefineTemplate(SelTreeNode.Data);
473 PrevDefNode:=SelDefNode.Prior;
474 if (SelDefNode.IsAutoGenerated) or (PrevDefNode.IsAutoGenerated) then begin
475 IDEMessageDialog(lisCodeToolsDefsNodeIsReadonly,
476 lisCodeToolsDefsAutoGeneratedNodesCanNotBeEdited,
477 mtInformation,[mbCancel]);
478 exit;
479 end;
480 if (not (PrevDefNode.Action in DefineActionBlocks)) then begin
481 IDEMessageDialog(lisCodeToolsDefsInvalidPreviousNode,
482 lisCodeToolsDefsPreviousNodeCanNotContainChildNodes,
483 mtInformation,[mbCancel]);
484 exit;
485 end;
486 // move node one lvl down in TreeView
487 SelTreeNode.MoveTo(SelTreeNode.GetPrevSibling,naAddChild);
488 // move node one lvl up in DefineTree
489 SelDefNode.Unbind;
490 PrevDefNode.AddChild(SelDefNode);
491 SetNodeImages(SelTreeNode.Parent,true);
492 SelTreeNode.MakeVisible;
493 end;
494
495 procedure TCodeToolsDefinesEditor.DeleteNodeMenuItemClick(Sender: TObject);
496 var
497 SelTreeNode: TTreeNode;
498 SelDefNode: TDefineTemplate;
499 begin
500 SelTreeNode:=DefineTreeView.Selected;
501 SaveSelectedValues;
502 if (SelTreeNode=nil) then exit;
503 SelDefNode:=TDefineTemplate(SelTreeNode.Data);
504 if (SelDefNode.IsAutoGenerated) then begin
505 IDEMessageDialog(lisCodeToolsDefsNodeIsReadonly,
506 lisCodeToolsDefsAutoGeneratedNodesCanNotBeEdited,
507 mtInformation,[mbCancel]);
508 exit;
509 end;
510 if FLastSelectedNode=SelTreeNode then FLastSelectedNode:=nil;
511 // delete node in TreeView
512 SelTreeNode.Free;
513 // delete node in DefineTree
514 SelDefNode.Unbind;
515 SelDefNode.Free;
516 end;
517
518 procedure TCodeToolsDefinesEditor.ConvertActionMenuItemClick(Sender: TObject);
519 var
520 NewAction: TDefineAction;
521 SelTreeNode: TTreeNode;
522 SelDefNode: TDefineTemplate;
523 begin
524 SelTreeNode:=DefineTreeView.Selected;
525 SaveSelectedValues;
526 if SelTreeNode=nil then exit;
527 SelDefNode:=TDefineTemplate(SelTreeNode.Data);
528 if (SelDefNode.IsAutoGenerated) then begin
529 IDEMessageDialog(lisCodeToolsDefsNodeIsReadonly,
530 lisCodeToolsDefsAutoGeneratedNodesCanNotBeEdited,
531 mtInformation,[mbCancel]);
532 exit;
533 end;
534 if Sender=ConvertActionToDefineMenuItem then NewAction:=da_Define
535 else if Sender=ConvertActionToDefineRecurseMenuItem then NewAction:=da_DefineRecurse
536 else if Sender=ConvertActionToUndefineMenuItem then NewAction:=da_Undefine
537 else if Sender=ConvertActionToUndefineRecurseMenuItem then NewAction:=da_UndefineRecurse
538 else if Sender=ConvertActionToUndefineAllMenuItem then NewAction:=da_UndefineAll
539 else if Sender=ConvertActionToBlockMenuItem then NewAction:=da_Block
540 else if Sender=ConvertActionToDirectoryMenuItem then NewAction:=da_Directory
541 else if Sender=ConvertActionToIfMenuItem then NewAction:=da_If
542 else if Sender=ConvertActionToIfDefMenuItem then NewAction:=da_IfDef
543 else if Sender=ConvertActionToIfNotDefMenuItem then NewAction:=da_IfNDef
544 else if Sender=ConvertActionToElseIfMenuItem then NewAction:=da_ElseIf
545 else if Sender=ConvertActionToElseMenuItem then NewAction:=da_Else
546 else NewAction:=da_None;
547 SelDefNode.Action:=NewAction;
548 SetNodeImages(SelTreeNode,false);
549 SetTypeLabel;
550 end;
551
552 procedure TCodeToolsDefinesEditor.OpenPreviewMenuItemClick(Sender: TObject);
553 begin
554 // apply changed tree
555 CodeToolBoss.DefineTree.AssignNonAutoCreated(DefineTree);
556 try
557 // show preview
558 ShowCodeToolsDefinesValuesDialog(DefineTree,'');
559 finally
560 // restore old tree
561 CodeToolsOpts.AssignGlobalDefineTemplatesToTree(CodeToolBoss.DefineTree);
562 end;
563 end;
564
565 procedure TCodeToolsDefinesEditor.InsertFPCProjectDefinesTemplateMenuItemClick(
566 Sender: TObject);
567 var InputFileDlg: TInputFileDialog;
568 DefaultFPCSrcDir, DefaultCompiler,
569 CompilerPath, FPCSrcDir: string;
570 DirTemplate, FPCTemplate: TDefineTemplate;
571 TargetOS, TargetProcessor: string;
572 UnitSetCache: TFPCUnitSetCache;
573 begin
574 InputFileDlg:=GetInputFileDialog;
575 InputFileDlg.Macros:=Macros;
576 with InputFileDlg do begin
577
578 DefaultFPCSrcDir:='$(FPCSrcDir)';
579 DefaultCompiler:=DefaultCompilerPath;
580
581 BeginUpdate;
582 Caption:=lisCodeToolsDefsCreateFPCMacrosAndPathsForAFPCProjectDirectory;
583
584 FileCount:=3;
585
586 FileTitles[0]:=lisCodeToolsDefsProjectDirectory;
587 FileDescs[0]:=lisCodeToolsDefsTheFreePascalProjectDirectory;
588 FileNames[0]:='';
589 FileFlags[0]:=[iftDirectory,iftNotEmpty,iftMustExist];
590
591 FileTitles[1]:=lisCodeToolsDefscompilerPath;
592 FileDescs[1]:=BreakString(
593 lisCodeToolsDefsThePathToTheFreePascalCompilerForThisProject, 60, 0);
594 FileNames[1]:=DefaultCompiler;
595 FileFlags[1]:=[iftFilename];
596
597 FileTitles[2]:=lisCodeToolsDefsFPCSVNSourceDirectory;
598 FileDescs[2]:=BreakString(
599 lisCodeToolsDefsTheFreePascalCVSSourceDirectory, 60, 0);
600 FileNames[2]:=DefaultFPCSrcDir;
601 FileFlags[2]:=[iftDirectory];
602
603 EndUpdate;
604 if ShowModal=mrCancel then exit;
605
606 FPCSrcDir:=FileNames[2];
607 if Macros<>nil then Macros.SubstituteStr(FPCSrcDir);
608 if FPCSrcDir='' then FPCSrcDir:=DefaultFPCSrcDir;
609 DebugLn(' FPCSrcDir="',FPCSrcDir,'"');
610
611 // ask the compiler for Macros
612 CompilerPath:=FileNames[1];
613 if Macros<>nil then Macros.SubstituteStr(CompilerPath);
614 DebugLn(' CompilerPath="',CompilerPath,'"');
615 TargetOS:='';
616 TargetProcessor:='';
617
618 UnitSetCache:=Boss.CompilerDefinesCache.FindUnitSet(CompilerPath,
619 TargetOS,TargetProcessor,'',FPCSrcDir,true);
620
621 // create directory defines
622 DirTemplate:=TDefineTemplate.Create('FPC Project ('+FileNames[0]+')',
623 'Free Pascal Project Directory','',FileNames[0],da_Directory);
624
625 if (DefaultFPCSrcDir=Filenames[2]) and (DefaultCompiler=Filenames[1]) then
626 begin
627 // a normal fpc project -> nothing special needed
628 end else begin
629 // a special fpc project -> create a world of its own
630 DirTemplate.AddChild(TDefineTemplate.Create('Reset All',
631 'Reset all values','','',da_UndefineAll));
632 FPCTemplate:=CreateFPCTemplate(UnitSetCache,CodeToolsOpts);
633 if FPCTemplate<>nil then
634 DirTemplate.AddChild(FPCTemplate);
635 end;
636
637 DirTemplate.SetDefineOwner(CodeToolsOpts,true);
638 InsertTemplate(DirTemplate);
639 end;
640 end;
641
642 procedure TCodeToolsDefinesEditor.InsertFPCompilerDefinesTemplateMenuItemClick(
643 Sender: TObject);
644 var InputFileDlg: TInputFileDialog;
645 CompilerPath, DefaultCompiler: string;
646 FPCTemplate: TDefineTemplate;
647 UnitSearchPath, TargetOS, TargetProcessor: string;
648 begin
649 InputFileDlg:=GetInputFileDialog;
650 InputFileDlg.Macros:=Macros;
651 with InputFileDlg do begin
652 DefaultCompiler:=DefaultCompilerPath;
653
654 BeginUpdate;
655 Caption:=lisCodeToolsDefsCreateDefinesForFreePascalCompiler;
656 FileCount:=1;
657
658 FileTitles[0]:=lisCodeToolsDefscompilerPath;
659 FileDescs[0]:=Format(
660 lisCodeToolsDefsThePathToTheFreePascalCompilerForExample, [LineEnding,
661 '"', GetDefaultCompilerFilename, '"', '"', '"']);
662 FileNames[0]:=DefaultCompiler;
663 FileFlags[0]:=[iftCmdLine,iftNotEmpty];
664
665 EndUpdate;
666 if ShowModal=mrCancel then exit;
667
668 CompilerPath:=FileNames[0];
669 if Macros<>nil then Macros.SubstituteStr(CompilerPath);
670 DebugLn(' CompilerPath="',CompilerPath,'"');
671
672 FPCTemplate:=Boss.DefinePool.CreateFPCTemplate(CompilerPath,'',
673 CreateCompilerTestPascalFilename,
674 UnitSearchPath,
675 TargetOS,TargetProcessor,
676 CodeToolsOpts);
677 if (TargetOS='') or (TargetProcessor='') or (UnitSearchPath='') then
678 DebugLn(['TCodeToolsDefinesEditor.InsertFPCompilerDefinesTemplateMenuItemClick TargetOS="',TargetOS,'" TargetProcessor="',TargetProcessor,'"']);
679 if FPCTemplate=nil then exit;
680 FPCTemplate.Name:='Free Pascal Compiler ('+CompilerPath+')';
681 InsertTemplate(FPCTemplate);
682 end;
683 end;
684
685 procedure TCodeToolsDefinesEditor.InsertFPCSourceDirDefinesTemplateMenuItemClick
686 (Sender: TObject);
687 var InputFileDlg: TInputFileDialog;
688 DefaultCompiler, CompilerPath, FPCSrcDir: string;
689 TargetOS, TargetProcessor: string;
690 FPCSrcTemplate: TDefineTemplate;
691 UnitSetCache: TFPCUnitSetCache;
692 begin
693 InputFileDlg:=GetInputFileDialog;
694 InputFileDlg.Macros:=Macros;
695 with InputFileDlg do begin
696 DefaultCompiler:=DefaultCompilerPath;
697
698 BeginUpdate;
699 Caption:=lisCodeToolsDefsCreateDefinesForFreePascalSVNSources;
700 FileCount:=2;
701
702 FileTitles[0]:=lisCodeToolsDefsFPCSVNSourceDirectory;
703 FileDescs[0]:=lisCodeToolsDefsTheFreePascalSVNSourceDir;
704 FileNames[0]:='~/fpc_sources/2.4.1/fpc';
705 FileFlags[0]:=[iftDirectory,iftNotEmpty,iftMustExist];
706
707 FileTitles[1]:=lisCodeToolsDefsCompilerPath;
708 FileDescs[1]:=Format(
709 lisCodeToolsDefsThePathToTheFreePascalCompilerForThisSourceUsedToA, [LineEnding]);
710 FileNames[1]:=DefaultCompiler;
711 FileFlags[1]:=[iftFilename];
712
713 EndUpdate;
714 if ShowModal=mrCancel then exit;
715
716 // ask the compiler for Macros
717 CompilerPath:=FileNames[1];
718 if Macros<>nil then Macros.SubstituteStr(CompilerPath);
719 DebugLn(' CompilerPath="',CompilerPath,'"');
720
721 TargetOS:='';
722 TargetProcessor:='';
723 FPCSrcDir:=FileNames[0];
724 if Macros<>nil then Macros.SubstituteStr(FPCSrcDir);
725 DebugLn(' FPCSrcDir="',FPCSrcDir,'"');
726
727 UnitSetCache:=Boss.CompilerDefinesCache.FindUnitSet(CompilerPath,
728 TargetOS,TargetProcessor,'',FPCSrcDir,true);
729 // create FPC Source defines
730 FPCSrcTemplate:=CreateFPCSourceTemplate(UnitSetCache,CodeToolsOpts);
731 if FPCSrcTemplate=nil then begin
732 DebugLn('ERROR: unable to create FPC CVS Src defines for "',FPCSrcDir,'"');
733 exit;
734 end;
735
736 // create directory defines
737 FPCSrcTemplate.Name:='FPC SVN Sources ('+FileNames[0]+')';
738
739 FPCSrcTemplate.SetDefineOwner(CodeToolsOpts,true);
740 InsertTemplate(FPCSrcTemplate);
741 end;
742 end;
743
744 procedure TCodeToolsDefinesEditor.InsertDelphiCompilerDefinesTemplateMenuItemClick
745 (Sender: TObject);
746 var DelphiVersion: integer;
747 begin
748 if Sender=InsertDelphi7CompilerDefinesTemplateMenuItem then
749 DelphiVersion:=7
750 else if Sender=InsertDelphi6CompilerDefinesTemplateMenuItem then
751 DelphiVersion:=6
752 else
753 DelphiVersion:=5;
754 InsertTemplate(Boss.DefinePool.CreateDelphiCompilerDefinesTemplate(
755 DelphiVersion,CodeToolsOpts));
756 end;
757
758 procedure TCodeToolsDefinesEditor.InsertDelphiDirectoryTemplateMenuItemClick(
759 Sender: TObject);
760 var InputFileDlg: TInputFileDialog;
761 DirTemplate: TDefineTemplate;
762 DelphiVersion: integer;
763 DelphiName: string;
764 begin
765 if Sender=InsertDelphi7DirectoryTemplateMenuItem then
766 DelphiVersion:=7
767 else if Sender=InsertDelphi6DirectoryTemplateMenuItem then
768 DelphiVersion:=6
769 else
770 DelphiVersion:=5;
771 DelphiName:='Delphi'+IntToStr(DelphiVersion);
772
773 InputFileDlg:=GetInputFileDialog;
774 InputFileDlg.Macros:=Macros;
775 with InputFileDlg do begin
776 BeginUpdate;
777 Caption:=Format(lisCodeToolsDefsCreateDefinesForDirectory, [DelphiName]);
778 FileCount:=1;
779
780 FileTitles[0]:=Format(lisCodeToolsDefsdirectory, [DelphiName]);
781 FileDescs[0]:=Format(lisCodeToolsDefsDelphiMainDirectoryDesc, [DelphiName,
782 LineEnding, DelphiName, LineEnding, IntToStr(DelphiVersion)]);
783 FileNames[0]:=GetForcedPathDelims(
784 'C:/Programme/Borland/Delphi'+IntToStr(DelphiVersion));
785 FileFlags[0]:=[iftDirectory,iftNotEmpty,iftMustExist];
786
787 EndUpdate;
788 if ShowModal=mrCancel then exit;
789 DirTemplate:=Boss.DefinePool.CreateDelphiDirectoryTemplate(FileNames[0],
790 DelphiVersion,CodeToolsOpts);
791 if DirTemplate=nil then exit;
792 DirTemplate.Name:=DelphiName+' ('+FileNames[0]+')';
793 InsertTemplate(DirTemplate);
794 end;
795 end;
796
797 procedure TCodeToolsDefinesEditor.InsertDelphiProjectTemplateMenuItemClick(
798 Sender: TObject);
799 var
800 InputFileDlg: TInputFileDialog;
801 ProjTemplate: TDefineTemplate;
802 DelphiVersion: integer;
803 DelphiName: string;
804 begin
805 if Sender=InsertDelphi7ProjectTemplateMenuItem then
806 DelphiVersion:=7
807 else if Sender=InsertDelphi6ProjectTemplateMenuItem then
808 DelphiVersion:=6
809 else
810 DelphiVersion:=5;
811 DelphiName:='Delphi'+IntToStr(DelphiVersion);
812
813 InputFileDlg:=GetInputFileDialog;
814 InputFileDlg.Macros:=Macros;
815 with InputFileDlg do begin
816 BeginUpdate;
817 Caption:=Format(lisCodeToolsDefsCreateDefinesForProject, [DelphiName]);
818
819 FileCount:=2;
820
821 FileTitles[0]:=Format(lisCodeToolsDefsprojectDirectory2, [DelphiName]);
822 FileDescs[0]:=Format(lisCodeToolsDefsTheProjectDirectory, [DelphiName, LineEnding]);
823 FileNames[0]:=GetForcedPathDelims('C:/Programme/Borland/Delphi'
824 +IntToStr(DelphiVersion)+'/YourProject');
825 FileFlags[0]:=[iftDirectory,iftNotEmpty,iftMustExist];
826
827 FileTitles[1]:=Format(lisCodeToolsDefsdirectory, [DelphiName]);
828 FileDescs[1]:=Format(lisCodeToolsDefsDelphiMainDirectoryForProject, [DelphiName,
829 LineEnding, DelphiName, LineEnding, DelphiName, LineEnding, IntToStr(DelphiVersion)]);
830 FileNames[1]:=GetForcedPathDelims('C:/Programme/Borland/Delphi'+IntToStr(DelphiVersion));
831 FileFlags[1]:=[iftDirectory,iftNotEmpty,iftMustExist];
832
833 EndUpdate;
834 if ShowModal=mrCancel then exit;
835 ProjTemplate:=Boss.DefinePool.CreateDelphiProjectTemplate(FileNames[0],
836 FileNames[1],DelphiVersion,CodeToolsOpts);
837 if ProjTemplate=nil then exit;
838 ProjTemplate.Name:=DelphiName+' Project ('+FileNames[0]+')';
839 InsertTemplate(ProjTemplate);
840 end;
841 end;
842
843 procedure TCodeToolsDefinesEditor.InsertKylixCompilerDefinesTemplateMenuItemClick
844 (Sender: TObject);
845 var KylixVersion: integer;
846 begin
847 KylixVersion:=3;
848 InsertTemplate(Boss.DefinePool.CreateKylixCompilerDefinesTemplate(
849 KylixVersion,CodeToolsOpts));
850 end;
851
852 procedure TCodeToolsDefinesEditor.InsertKylixDirectoryTemplateMenuItemClick(
853 Sender: TObject);
854 var
855 InputFileDlg: TInputFileDialog;
856 DirTemplate: TDefineTemplate;
857 KylixVersion: integer;
858 KylixName: string;
859 UserName: String;
860 begin
861 KylixVersion:=3;
862 KylixName:='Kylix'+IntToStr(KylixVersion);
863
864 UserName:=GetCurrentUserName;
865 if UserName='' then UserName:='user';
866 InputFileDlg:=GetInputFileDialog;
867 InputFileDlg.Macros:=Macros;
868 with InputFileDlg do begin
869 BeginUpdate;
870 Caption:=Format(lisCodeToolsDefsCreateDefinesForDirectory, [KylixName]);
871 FileCount:=1;
872
873 FileTitles[0]:=Format(lisCodeToolsDefsdirectory, [KylixName]);
874 FileDescs[0]:=Format(lisCodeToolsDefsKylixMainDirectoryDesc, [KylixName,
875 LineEnding, KylixName, LineEnding, IntToStr(KylixVersion)]);
876 FileNames[0]:=GetForcedPathDelims('/home/'+UserName+'/kylix'+IntToStr(KylixVersion));
877 FileFlags[0]:=[iftDirectory,iftNotEmpty,iftMustExist];
878
879 EndUpdate;
880 if ShowModal=mrCancel then exit;
881 DirTemplate:=Boss.DefinePool.CreateKylixDirectoryTemplate(FileNames[0],
882 KylixVersion,CodeToolsOpts);
883 if DirTemplate=nil then exit;
884 DirTemplate.Name:=KylixName+' ('+FileNames[0]+')';
885 InsertTemplate(DirTemplate);
886 end;
887 end;
888
889 procedure TCodeToolsDefinesEditor.InsertKylixProjectTemplateMenuItemClick(
890 Sender: TObject);
891 var
892 InputFileDlg: TInputFileDialog;
893 ProjTemplate: TDefineTemplate;
894 KylixVersion: integer;
895 KylixName: string;
896 UserName: String;
897 begin
898 KylixVersion:=3;
899 KylixName:='Kylix'+IntToStr(KylixVersion);
900
901 UserName:=GetCurrentUserName;
902 if UserName='' then UserName:='user';
903 InputFileDlg:=GetInputFileDialog;
904 InputFileDlg.Macros:=Macros;
905 with InputFileDlg do begin
906 BeginUpdate;
907 Caption:=Format(lisCodeToolsDefsCreateDefinesForProject, [KylixName]);
908
909 FileCount:=2;
910
911 FileTitles[0]:=Format(lisCodeToolsDefsprojectDirectory2, [KylixName]);
912 FileDescs[0]:=Format(lisCodeToolsDefsTheProjectDirectory, [KylixName, LineEnding]
913 );
914 FileNames[0]:=GetForcedPathDelims('/home/'+UserName+'/kylix'
915 +IntToStr(KylixVersion)+'/YourProject');
916 FileFlags[0]:=[iftDirectory,iftNotEmpty,iftMustExist];
917
918 FileTitles[1]:=Format(lisCodeToolsDefsdirectory, [KylixName]);
919 FileDescs[1]:=Format(lisCodeToolsDefsKylixMainDirectoryForProject, [KylixName,
920 LineEnding, KylixName, LineEnding, KylixName, LineEnding, IntToStr(KylixVersion)
921 ]);
922 FileNames[1]:=GetForcedPathDelims('/home/'+UserName+'/kylix'+IntToStr(KylixVersion));
923 FileFlags[1]:=[iftDirectory,iftNotEmpty,iftMustExist];
924
925 EndUpdate;
926 if ShowModal=mrCancel then exit;
927 ProjTemplate:=Boss.DefinePool.CreateDelphiProjectTemplate(FileNames[0],
928 FileNames[1],KylixVersion,CodeToolsOpts);
929 if ProjTemplate=nil then exit;
930 ProjTemplate.Name:=KylixName+' Project ('+FileNames[0]+')';
931 InsertTemplate(ProjTemplate);
932 end;
933 end;
934
935 procedure TCodeToolsDefinesEditor.CreateComponents;
936 var
937 DefAction: TDefineAction;
938 begin
939 // edit nodes
940 EditMenuItem.Caption := lisEdit;
941 MoveNodeUpMenuItem.Caption:=lisCodeToolsDefsMoveNodeUp;
942 MoveNodeDownMenuItem.Caption := lisCodeToolsDefsMoveNodeDown;
943 MoveNodeLvlUpMenuItem.Caption := lisCodeToolsDefsMoveNodeOneLevelUp;
944 MoveNodeLvlDownMenuItem.Caption := lisCodeToolsDefsMoveNodeOneLevelDown;
945 InsertBehindMenuItem.Caption := lisCodeToolsDefsInsertNodeBelow;
946 InsertAsChildMenuItem.Caption := lisCodeToolsDefsInsertNodeAsChild;
947 DeleteNodeMenuItem.Caption := lisCodeToolsDefsDeleteNode;
948 ConvertActionMenuItem.Caption := lisCodeToolsDefsConvertNode;
949
950 // insert node behind submenu
951 InsertBehindDefineMenuItem.Caption := lisCodeToolsDefsDefine;
952 InsertBehindDefineRecurseMenuItem.Caption := lisCodeToolsDefsDefineRecurse;
953 InsertBehindUndefineMenuItem.Caption := lisCodeToolsDefsUndefine;
954 InsertBehindUndefineRecurseMenuItem.Caption := lisCodeToolsDefsUndefineRecurse;
955 InsertBehindUndefineAllMenuItem.Caption := lisCodeToolsDefsUndefineAll;
956 InsertBehindBlockMenuItem.Caption := lisCodeToolsDefsBlock;
957 InsertBehindDirectoryMenuItem.Caption := lisCodeToolsDefsInsertBehindDirectory;
958 InsertBehindIfMenuItem.Caption := lisCodeToolsDefsIf;
959 InsertBehindIfDefMenuItem.Caption := lisCodeToolsDefsIfDef;
960 InsertBehindIfNotDefMenuItem.Caption := lisCodeToolsDefsIfNDef;
961 InsertBehindElseIfMenuItem.Caption := lisCodeToolsDefsElseIf;
962 InsertBehindElseMenuItem.Caption := lisCodeToolsDefsElse;
963
964 // insert node as child submenu
965 InsertAsChildDefineMenuItem.Caption := lisCodeToolsDefsDefine;
966 InsertAsChildDefineRecurseMenuItem.Caption := lisCodeToolsDefsDefineRecurse;
967 InsertAsChildUndefineMenuItem.Caption := lisCodeToolsDefsUndefine;
968 InsertAsChildUndefineRecurseMenuItem.Caption := lisCodeToolsDefsUndefineRecurse;
969 InsertAsChildUndefineAllMenuItem.Caption := lisCodeToolsDefsUndefineAll;
970 InsertAsChildBlockMenuItem.Caption := lisCodeToolsDefsBlock;
971 InsertAsChildDirectoryMenuItem.Caption := lisCodeToolsDefsInsertBehindDirectory;
972 InsertAsChildIfMenuItem.Caption := lisCodeToolsDefsIf;
973 InsertAsChildIfDefMenuItem.Caption := lisCodeToolsDefsIfDef;
974 InsertAsChildIfNotDefMenuItem.Caption := lisCodeToolsDefsIfNDef;
975 InsertAsChildElseIfMenuItem.Caption := lisCodeToolsDefsElseIf;
976 InsertAsChildElseMenuItem.Caption := lisCodeToolsDefsElse;
977
978 // convert node sub menu
979 ConvertActionToDefineMenuItem.Caption := lisCodeToolsDefsDefine;
980 ConvertActionToDefineRecurseMenuItem.Caption := lisCodeToolsDefsDefineRecurse;
981 ConvertActionToUndefineMenuItem.Caption := lisCodeToolsDefsUndefine;
982 ConvertActionToUndefineRecurseMenuItem.Caption := lisCodeToolsDefsUndefineRecurse;
983 ConvertActionToUndefineAllMenuItem.Caption := lisCodeToolsDefsUndefineAll;
984 ConvertActionToBlockMenuItem.Caption := lisCodeToolsDefsBlock;
985 ConvertActionToDirectoryMenuItem.Caption := lisCodeToolsDefsInsertBehindDirectory;
986 ConvertActionToIfMenuItem.Caption := lisCodeToolsDefsIf;
987 ConvertActionToIfDefMenuItem.Caption := lisCodeToolsDefsIfDef;
988 ConvertActionToIfNotDefMenuItem.Caption := lisCodeToolsDefsIfNDef;
989 ConvertActionToElseIfMenuItem.Caption := lisCodeToolsDefsElseIf;
990 ConvertActionToElseMenuItem.Caption := lisCodeToolsDefsElse;
991
992 // tools
993 ToolsMenuItem.Caption := lisCTDefsTools;
994 OpenPreviewMenuItem.Caption := lisCTDefsOpenPreview;
995
996 // templates
997 InsertTemplateMenuItem.Caption := lisCodeToolsDefsInsertTemplate;
998
999 // FPC templates
1000 InsertFPCProjectDefinesTemplateMenuItem.Caption := lisCodeToolsDefsInsertFreePascalProjectTe;
1001 InsertFPCompilerDefinesTemplateMenuItem.Caption := lisCodeToolsDefsInsertFreePascalCompilerT;
1002 InsertFPCSourceDirTemplateMenuItem.Caption := lisCodeToolsDefsInsertFreePascalSVNSource;
1003
1004 // Delphi 5 templates
1005 InsertDelphi5CompilerDefinesTemplateMenuItem.Caption := lisCodeToolsDefsInsertDelphi5CompilerTemp;
1006 InsertDelphi5DirectoryTemplateMenuItem.Caption := lisCodeToolsDefsInsertDelphi5DirectoryTem;
1007 InsertDelphi5ProjectTemplateMenuItem.Caption := lisCodeToolsDefsInsertDelphi5ProjectTempl;
1008
1009 // Delphi 6 templates
1010 InsertDelphi6CompilerDefinesTemplateMenuItem.Caption := lisCodeToolsDefsInsertDelphi6CompilerTemp;
1011 InsertDelphi6DirectoryTemplateMenuItem.Caption := lisCodeToolsDefsInsertDelphi6DirectoryTem;
1012 InsertDelphi6ProjectTemplateMenuItem.Caption := lisCodeToolsDefsInsertDelphi6ProjectTempl;
1013
1014 // Delphi 7 templates
1015 InsertDelphi7CompilerDefinesTemplateMenuItem.Caption := lisCodeToolsDefsInsertDelphi7CompilerTemp;
1016 InsertDelphi7DirectoryTemplateMenuItem.Caption := lisCodeToolsDefsInsertDelphi7DirectoryTem;
1017 InsertDelphi7ProjectTemplateMenuItem.Caption := lisCodeToolsDefsInsertDelphi7ProjectTempl;
1018
1019 // Kylix 3 templates
1020 InsertKylix3CompilerDefinesTemplateMenuItem.Caption := lisCodeToolsDefsInsertKylix3CompilerTemp;
1021 InsertKylix3DirectoryTemplateMenuItem.Caption := lisCodeToolsDefsInsertKylix3DirectoryTem;
1022 InsertKylix3ProjectTemplateMenuItem.Caption := lisCodeToolsDefsInsertKylix3ProjectTempl;
1023
1024 // selected item
1025 SelectedItemGroupBox.Caption:=lisCodeToolsDefsSelectedNode;
1026
1027 NameLabel.Caption:=lisCodeToolsDefsName;
1028 DescriptionLabel.Caption:=lisCodeToolsDefsDescription;
1029 VariableLabel.Caption:=lisCodeToolsDefsVariable;
1030
1031 ValueNotebook.Page[0].Caption := lisCodeToolsDefsValueAsText;
1032 ValueNotebook.Page[1].Caption := lisCodeToolsDefsValueAsFilePaths;
1033 ValueNotebook.PageIndex := 0;
1034
1035 MoveFilePathUpBitBtn.Caption:=lisUp;
1036 MoveFilePathDownBitBtn.Caption:=lisDown;
1037 DeleteFilePathBitBtn.Caption:=lisDelete;
1038 InsertFilePathBitBtn.Caption:=lisInsert;
1039
1040 DefineTreeView.Images := IDEImages.Images_24;
1041 DefineTreeView.StateImages := IDEImages.Images_16;
1042
1043 DefineActionImages[Low(TDefineAction)] := -1;
1044 for DefAction := Succ(Low(TDefineAction)) to High(TDefineAction) do
1045 DefineActionImages[DefAction] := IDEImages.LoadImage('da_' + LowerCase(DefineActionNames[DefAction]), 24);
1046
1047 AutogeneratedImage := IDEImages.LoadImage('laz_wand');
1048 end;
1049
TCodeToolsDefinesEditor.CreateSeperatornull1050 function TCodeToolsDefinesEditor.CreateSeperator : TMenuItem;
1051 begin
1052 Result := TMenuItem.Create(Self);
1053 Result.Caption := '-';
1054 end;
1055
1056 procedure TCodeToolsDefinesEditor.SetTransferMacros(
1057 const AValue: TTransferMacroList);
1058 begin
1059 FTransferMacros:=AValue;
1060 end;
1061
1062 procedure TCodeToolsDefinesEditor.ValueAsPathToValueAsText;
1063 var s: string;
1064 i, j, l: integer;
1065 begin
1066 s:=ValueAsFilePathsSynEdit.Text;
1067 l:=length(s);
1068 // replace line ends with semicolon
1069 i:=1;
1070 j:=1;
1071 while i<=l do begin
1072 if s[i] in [#10,#13] then begin
1073 inc(i);
1074 if (i<l) and (s[i] in [#10,#13]) and (s[i-1]<>s[i]) then begin
1075 inc(i);
1076 end;
1077 s[j]:=';';
1078 inc(j);
1079 end else begin
1080 s[j]:=s[i];
1081 inc(i);
1082 inc(j);
1083 end;
1084 end;
1085 dec(j);
1086 while (j>=1) and (s[j]=';') do dec(j);
1087 SetLength(s,j);
1088 ValueAsTextSynEdit.Text:=s;
1089 end;
1090
1091 procedure TCodeToolsDefinesEditor.SaveSelectedValues;
1092 var
1093 ATreeNode: TTreeNode;
1094 ADefNode: TDefineTemplate;
1095 s: string;
1096 l: integer;
1097 begin
1098 ATreeNode:=FLastSelectedNode;
1099 if (ATreeNode<>nil) then begin
1100 ADefNode:=TDefineTemplate(ATreeNode.Data);
1101 if (not ADefNode.IsAutoGenerated) then begin
1102 ADefNode.Name:=NameEdit.Text;
1103 ATreeNode.Text:=ADefNode.Name;
1104 ADefNode.Variable:=VariableEdit.Text;
1105 ADefNode.Description:=DescriptionEdit.Text;
1106 if ValueNoteBook.PageIndex=1 then
1107 ValueAsPathToValueAsText;
1108 s:=ValueAsTextSynEdit.Text;
1109 l:=length(s);
1110 if (l>0) and (s[l] in [#13,#10]) then begin
1111 // remove line end at end of Text, that was added automatically
1112 dec(l);
1113 if (l>0) and (s[l] in [#13,#10]) and (s[l]<>s[l+1]) then
1114 dec(l);
1115 SetLength(s,l);
1116 end;
1117 ADefNode.Value:=s;
1118 end;
1119 FLastSelectedNode:=nil;
1120 end;
1121 end;
1122
1123 procedure TCodeToolsDefinesEditor.ShowSelectedValues;
1124 var
1125 SelTreeNode: TTreeNode;
1126 SelDefNode: TDefineTemplate;
1127 begin
1128 SelTreeNode:=DefineTreeView.Selected;
1129 if SelTreeNode<>FLastSelectedNode then begin
1130 SaveSelectedValues;
1131 end;
1132 if SelTreeNode<>nil then begin
1133 SelDefNode:=TDefineTemplate(SelTreeNode.Data);
1134 SetValuesEditable(not SelDefNode.IsAutoGenerated);
1135 NameEdit.Text:=SelDefNode.Name;
1136 DescriptionEdit.Text:=SelDefNode.Description;
1137 VariableEdit.Text:=SelDefNode.Variable;
1138 ValueAsTextSynEdit.Text:=SelDefNode.Value;
1139 ValueAsFilePathsSynEdit.Text:=ValueToFilePathText(SelDefNode.Value);
1140 if SelDefNode.IsAutoGenerated then begin
1141 //ValueAsTextSynEdit.Options:=ValueAsTextSynEdit.Options+[eoNoCaret];
1142 ValueAsTextSynEdit.ReadOnly:=true;
1143 end else begin
1144 //ValueAsTextSynEdit.Options:=ValueAsTextSynEdit.Options-[eoNoCaret];
1145 ValueAsTextSynEdit.ReadOnly:=false;
1146 end;
1147 ValueAsFilePathsSynEdit.Options:=ValueAsTextSynEdit.Options;
1148 ValueAsFilePathsSynEdit.ReadOnly:=ValueAsTextSynEdit.ReadOnly;
1149 end else begin
1150 SetValuesEditable(false);
1151 NameEdit.Text:='';
1152 DescriptionEdit.Text:='';
1153 VariableEdit.Text:='';
1154 ValueAsTextSynEdit.Text:='';
1155 ValueAsFilePathsSynEdit.Text:='';
1156 end;
1157 SetTypeLabel;
1158 FLastSelectedNode:=SelTreeNode;
1159 end;
1160
1161 procedure TCodeToolsDefinesEditor.SetTypeLabel;
1162 var
1163 SelTreeNode: TTreeNode;
1164 SelDefNode: TDefineTemplate;
1165 s: string;
1166 begin
1167 SelTreeNode:=DefineTreeView.Selected;
1168 if SelTreeNode<>nil then begin
1169 SelDefNode:=TDefineTemplate(SelTreeNode.Data);
1170 s:=Format(lisCodeToolsDefsAction, [DefineActionNames[SelDefNode.Action]]);
1171 if SelDefNode.IsAutoGenerated then
1172 s:=Format(lisCodeToolsDefsautoGenerated, [s]);
1173 end else begin
1174 s:=lisCodeToolsDefsnoneSelected;
1175 end;
1176 TypeLabel.Caption:=s;
1177 end;
1178
ValueToFilePathTextnull1179 function TCodeToolsDefinesEditor.ValueToFilePathText(const AValue: string
1180 ): string;
1181 var i: integer;
1182 begin
1183 Result:=AValue;
1184 for i:=1 to length(Result) do
1185 if Result[i]=';' then Result[i]:=#13;
1186 end;
1187
1188 procedure TCodeToolsDefinesEditor.InsertNewNode(Behind: boolean;
1189 DefAction: TDefineAction);
1190 var SelTreeNode, NodeInFront, ParentNode,
1191 NewTreeNode: TTreeNode;
1192 NewDefNode: TDefineTemplate;
1193 NewName, NewDescription, NewVariable, NewValue: string;
1194 begin
1195 SelTreeNode:=DefineTreeView.Selected;
1196 SaveSelectedValues;
1197 NodeInFront:=nil;
1198 ParentNode:=nil;
1199 if SelTreeNode<>nil then begin
1200 // there is an selected node
1201 if Behind then begin
1202 // insert behind selected node
1203 NodeInFront:=SelTreeNode;
1204 ParentNode:=NodeInFront.Parent;
1205 end else begin
1206 // insert as last child of selected node
1207 ParentNode:=SelTreeNode;
1208 NodeInFront:=ParentNode.GetFirstChild;
1209 if NodeInFront<>nil then begin
1210 while NodeInFront.GetNextSibling<>nil do
1211 NodeInFront:=NodeInFront.GetNextSibling;
1212 end;
1213 end;
1214 end else begin
1215 // no node selected, add as last root node
1216 NodeInFront:=DefineTreeView.Items.GetLastNode;
1217 end;
1218 if (ParentNode<>nil) and (TDefineTemplate(ParentNode.Data).IsAutoGenerated)
1219 then begin
1220 IDEMessageDialog(lisCodeToolsDefsInvalidParent,
1221 Format(lisCodeToolsDefsAutoCreatedNodesReadOnly, [LineEnding]),
1222 mtInformation, [mbCancel]);
1223 exit;
1224 end;
1225 if (ParentNode<>nil)
1226 and (not (TDefineTemplate(ParentNode.Data).Action in DefineActionBlocks)) then
1227 begin
1228 IDEMessageDialog(lisCodeToolsDefsInvalidParentNode,
1229 lisCodeToolsDefsParentNodeCanNotContainCh,
1230 mtInformation,[mbCancel]);
1231 exit;
1232 end;
1233 NewName:=FindUniqueName;
1234 NewDescription:=NewName;
1235 NewVariable:='';
1236 NewValue:='';
1237 NewDefNode:=TDefineTemplate.Create(NewName,NewDescription,NewVariable,
1238 NewValue,DefAction);
1239 NewDefNode.Owner:=CodeToolsOpts;
1240 // add node to treeview
1241 if (NodeInFront<>nil) then
1242 // insert in front
1243 NewTreeNode:=DefineTreeView.Items.InsertObjectBehind(
1244 NodeInFront,NewName,NewDefNode)
1245 else
1246 // add as last child
1247 NewTreeNode:=DefineTreeView.Items.AddChildObject(ParentNode,NewName,
1248 NewDefNode);
1249
1250 // add node to define tree
1251 if NodeInFront<>nil then
1252 NewDefNode.InsertBehind(TDefineTemplate(NodeInFront.Data))
1253 else if ParentNode<>nil then
1254 TDefineTemplate(ParentNode.Data).AddChild(NewDefNode)
1255 else
1256 FDefineTree.Add(NewDefNode);
1257
1258 SetNodeImages(NewTreeNode,true);
1259 DefineTreeView.Selected:=NewTreeNode;
1260 ShowSelectedValues;
1261 end;
1262
1263 procedure TCodeToolsDefinesEditor.InsertTemplate(NewTemplate: TDefineTemplate);
1264
1265 procedure AddChilds(ATreeNode: TTreeNode);
1266 var ADefNode, ChildDefNode: TDefineTemplate;
1267 ChildTreeNode: TTreeNode;
1268 begin
1269 if ATreeNode=nil then exit;
1270 ADefNode:=TDefineTemplate(ATreeNode.Data);
1271 ChildDefNode:=ADefNode.FirstChild;
1272 while ChildDefNode<>nil do begin
1273 ChildTreeNode:=DefineTreeView.Items.AddChildObject(ATreeNode,
1274 ChildDefNode.Name,ChildDefNode);
1275 AddChilds(ChildTreeNode);
1276 ChildDefNode:=ChildDefNode.Next;
1277 end;
1278 end;
1279
1280 var
1281 SelTreeNode, NewTreeNode: TTreeNode;
1282 SelDefNode: TDefineTemplate;
1283 begin
1284 SaveSelectedValues;
1285 if NewTemplate=nil then exit;
1286 NewTemplate.RemoveFlags([dtfAutoGenerated]);
1287 FLastSelectedNode:=nil;
1288 SelTreeNode:=DefineTreeView.Selected;
1289 if SelTreeNode<>nil then begin
1290 // insert behind selected node
1291 SelDefNode:=TDefineTemplate(SelTreeNode.Data);
1292 // insert in TreeView
1293 NewTreeNode:=DefineTreeView.Items.InsertObjectBehind(SelTreeNode,
1294 NewTemplate.Name,NewTemplate);
1295 // insert in DefineTree
1296 NewTemplate.InsertBehind(SelDefNode);
1297 end else begin
1298 // add as last root node
1299 // add in TreeView
1300 NewTreeNode:=DefineTreeView.Items.AddObject(nil,NewTemplate.Name,NewTemplate);
1301 // add in DefineTree
1302 DefineTree.Add(NewTemplate);
1303 end;
1304 // add children to TreeView
1305 AddChilds(NewTreeNode);
1306 // show and select
1307 SetNodeImages(NewTreeNode,true);
1308 NewTreeNode.Selected:=true;
1309 ShowSelectedValues;
1310 end;
1311
FindUniqueNamenull1312 function TCodeToolsDefinesEditor.FindUniqueName: string;
1313 var i: integer;
1314 begin
1315 i:=1;
1316 while (DefineTree.FindDefineTemplateByName(lisCodeToolsDefsNewNode+IntToStr(i
1317 ), false)<>nil)
1318 do inc(i);
1319 Result:=lisCodeToolsDefsNewNode+IntToStr(i);
1320 end;
1321
TCodeToolsDefinesEditor.ConsistencyChecknull1322 function TCodeToolsDefinesEditor.ConsistencyCheck: integer;
1323
CheckNodenull1324 function CheckNode(ATreeNode: TTreeNode): integer;
1325 var ADefNode, DummyDefNode: TDefineTemplate;
1326 begin
1327 if ATreeNode=nil then exit(0);
1328 ADefNode:=TDefineTemplate(ATreeNode.Data);
1329 //debugln(' CheckNode "',ATreeNode.Text,'" "',ADefNode.Name,'"');
1330 if ADefNode=nil then begin
1331 Result:=-1; exit;
1332 end;
1333 if (ATreeNode.GetPrevSibling<>nil)
1334 and (TDefineTemplate(ATreeNode.GetPrevSibling.Data)<>ADefNode.Prior) then
1335 begin
1336 Result:=-2; exit;
1337 end;
1338 if (ATreeNode.GetNextSibling<>nil)
1339 and (TDefineTemplate(ATreeNode.GetNextSibling.Data)<>ADefNode.Next) then
1340 begin
1341 DbgOut(' ERROR: ',ATreeNode.GetNextSibling.Text,' ');
1342 if ADefNode.Next<>nil then DbgOut('ADefNode.Next=',ADefNode.Next.Name,' ')
1343 else DbgOut('ADefNode.Next=nil ');
1344 DummyDefNode:=TDefineTemplate(ATreeNode.GetNextSibling.Data);
1345 if DummyDefNode<>nil then
1346 DebugLn('ATreeNode.GetNextSibling.Next=',DummyDefNode.Name)
1347 else
1348 DebugLn('ATreeNode.GetNextSibling.Next=nil');
1349 Result:=-3; exit;
1350 end;
1351 if (ATreeNode.GetFirstChild<>nil)
1352 and (TDefineTemplate(ATreeNode.GetFirstChild.Data)<>ADefNode.FirstChild)
1353 then begin
1354 Result:=-4; exit;
1355 end;
1356 Result:=CheckNode(ATreeNode.GetFirstChild);
1357 if Result<0 then exit;
1358 Result:=CheckNode(ATreeNode.GetNextSibling);
1359 if Result<0 then exit;
1360 end;
1361
1362 begin
1363 DefineTreeView.ConsistencyCheck;
1364 DefineTree.ConsistencyCheck;
1365 Result:=CheckNode(DefineTreeView.Items.GetFirstNode);
1366 if Result<0 then begin
1367 dec(Result,300000);
1368 exit;
1369 end;
1370 Result:=0;
1371 end;
1372
1373 procedure TCodeToolsDefinesEditor.SetValuesEditable(AValue: boolean);
1374 begin
1375 SelectedItemGroupBox.Enabled:=true;
1376 TypeLabel.Enabled:=true;
1377 NameLabel.Enabled:=AValue;
1378 NameEdit.Enabled:=AValue;
1379 DescriptionLabel.Enabled:=AValue;
1380 DescriptionEdit.Enabled:=AValue;
1381 VariableLabel.Enabled:=AValue;
1382 VariableEdit.Enabled:=AValue;
1383 ValueAsTextSynEdit.ReadOnly:=not AValue;
1384 ValueAsFilePathsSynEdit.ReadOnly:=not AValue;
1385 MoveFilePathUpBitBtn.Enabled:=AValue;
1386 MoveFilePathDownBitBtn.Enabled:=AValue;
1387 DeleteFilePathBitBtn.Enabled:=AValue;
1388 InsertFilePathBitBtn.Enabled:=AValue;
1389 end;
1390
1391 procedure TCodeToolsDefinesEditor.SetOptions(ACodeToolBoss: TCodeToolManager);
1392 begin
1393 FLastSelectedNode:=nil;
1394 FBoss:=ACodeToolBoss;
1395 FDefineTree.Assign(ACodeToolBoss.DefineTree);
1396 RebuildDefineTreeView(DefineTreeView,DefineTree.RootTemplate);
1397 ShowSelectedValues;
1398 end;
1399
1400 constructor TCodeToolsDefinesEditor.Create(TheOwner: TComponent);
1401 begin
1402 inherited Create(TheOwner);
1403
1404 IDEDialogLayoutList.ApplyLayout(Self,500,460);
1405
1406 Caption:=lisCodeToolsDefsCodeToolsDefinesEditor;
1407
1408 CreateComponents;
1409 MainSplitter.SetSplitterPosition(
1410 Max(20,Min(ClientHeight-100,CodeToolsOpts.DefinesEditMainSplitterTop)));
1411
1412 FDefineTree:=TDefineTree.Create;
1413
1414 EditorOpts.GetSynEditSettings(ValueAsTextSynEdit);
1415 ValueAsTextSynEdit.Gutter.Visible:=false;
1416 EditorOpts.GetSynEditSettings(ValueAsFilePathsSynEdit);
1417 ValueAsFilePathsSynEdit.Gutter.Visible:=false;
1418 end;
1419
1420 destructor TCodeToolsDefinesEditor.Destroy;
1421 begin
1422 FDefineTree.Free;
1423 inherited Destroy;
1424 end;
1425
1426 end.
1427
1428