1 unit compiler_path_options;
2
3 {$mode objfpc}{$H+}
4
5 interface
6
7 uses
8 Classes, SysUtils,
9 // LCL
10 LCLProc, LCLType,Controls, Dialogs, Buttons, StdCtrls,
11 // LazUtils
12 LazFileUtils, LazFileCache,
13 // IdeIntf
14 IDEOptionsIntf, IDEOptEditorIntf, MacroIntf, CompOptsIntf, IDEImagesIntf, IDEDialogs,
15 // IDE
16 Project, CompilerOptions, LazarusIDEStrConsts, PathEditorDlg, IDEProcs,
17 CheckCompilerOpts, ShowCompilerOpts, ImExportCompilerOpts;
18
19 type
20
21 { TCompilerPathOptionsFrame }
22
23 TCompilerPathOptionsFrame = class(TAbstractIDEOptionsEditor)
24 DebugPathEdit: TEdit;
25 DebugPathLabel: TLabel;
26 IncludeFilesEdit: TEdit;
27 IncludeFilesLabel: TLabel;
28 LibrariesEdit: TEdit;
29 LibrariesLabel: TLabel;
30 OtherSourcesEdit: TEdit;
31 OtherSourcesLabel: TLabel;
32 OtherUnitsEdit: TEdit;
33 OtherUnitsLabel: TLabel;
34 ProjTargetApplyConventionsCheckBox: TCheckBox;
35 ProjTargetFileEdit: TEdit;
36 ProjTargetFileLabel: TLabel;
37 UnitOutputDirEdit: TEdit;
38 UnitOutputDirLabel: TLabel;
39 procedure ProjTargetFileEditChange(Sender: TObject);
40 private
41 FDialog: TAbstractOptionsEditorDialog;
42 FCompilerOpts: TBaseCompilerOptions;
43 FHasProjectCompilerOpts: boolean;
44 OtherUnitsPathEditBtn: TPathEditorButton;
45 IncludeFilesPathEditBtn: TPathEditorButton;
46 OtherSourcesPathEditBtn: TPathEditorButton;
47 LibrariesPathEditBtn: TPathEditorButton;
48 btnUnitOutputDir: TButton;
49 DebugPathEditBtn: TPathEditorButton;
50 btnShowOptions: TBitBtn;
51 btnCheck: TBitBtn;
52 btnLoadSave: TBitBtn;
53 btnExport: TBitBtn;
54 chkUseAsDefault: TCheckBox;
CheckSrcPathInUnitPathnull55 function CheckSrcPathInUnitPath(OldParsedSrcPath, NewParsedSrcPath,
56 OldParsedUnitPath, NewParsedUnitPath: string;
57 out SrcPathChanged: boolean): boolean;
58 procedure FileBrowseBtnClick(Sender: TObject);
59 procedure PathEditBtnClick(Sender: TObject);
PathEditBtnExecutednull60 function PathEditBtnExecuted(Context: String; var NewPath: String): Boolean;
61 procedure DoShowOptions(Sender: TObject);
62 procedure DoCheck(Sender: TObject);
63 procedure DoImport(Sender: TObject);
64 procedure DoExport(Sender: TObject);
65 protected
66 procedure DoSaveSettings(AOptions: TAbstractIDEOptions);
67 procedure UpdateTargetFileLabel;
68 public
69 constructor Create(TheOwner: TComponent); override;
Checknull70 function Check: boolean; override;
GetTitlenull71 function GetTitle: string; override;
72 procedure Setup(ADialog: TAbstractOptionsEditorDialog); override;
73 procedure ReadSettings(AOptions: TAbstractIDEOptions); override;
74 procedure WriteSettings(AOptions: TAbstractIDEOptions); override;
SupportedOptionsClassnull75 class function SupportedOptionsClass: TAbstractIDEOptionsClass; override;
76 end;
77
78 implementation
79
80 {$R *.lfm}
81
CheckSearchPathnull82 function CheckSearchPath(const Context, ExpandedPath: string; Level: TCheckCompileOptionsMsgLvl; Hint: string = ''): boolean;
83 var
84 CurPath: string;
85 p: integer;
86 HasChars: TCCOSpecialChars;
87 ErrorMsg: string;
88 begin
89 Result := False;
90
91 if Hint<>'' then Hint:=#13#13+Hint;
92
93 // check for *
94 if Ord(Level) <= Ord(ccomlHints) then
95 begin
96 if System.Pos('*', ExpandedPath) > 0 then
97 begin
98 if IDEMessageDialog(lisHint, Format(
99 lisTheContainsAStarCharacterLazarusUsesThisAsNormalCh, [Context, LineEnding])+Hint,
100 mtWarning, [mbOK, mbCancel]) <> mrOk then
101 exit;
102 end;
103 end;
104
105 // check for non existing directories
106 if Ord(Level) <= Ord(ccomlWarning) then
107 begin
108 p := 1;
109 repeat
110 //DebugLn(['CheckSearchPath ',ExpandedPath,' ',p,' ',length(ExpandedPath)]);
111 CurPath := GetNextDirectoryInSearchPath(ExpandedPath, p);
112 if (CurPath <> '') and (not IDEMacros.StrHasMacros(CurPath)) and
113 (FilenameIsAbsolute(CurPath)) then
114 begin
115 if not DirPathExistsCached(CurPath) then
116 begin
117 if IDEMessageDialog(lisCCOWarningCaption, Format(
118 lisTheContainsANotExistingDirectory, [Context, LineEnding, CurPath])+Hint,
119 mtWarning, [mbIgnore, mbCancel]) <> mrIgnore then
120 Exit;
121 end;
122 end;
123 until p > length(ExpandedPath);
124 end;
125
126 // check for special characters
127 if (not IDEMacros.StrHasMacros(ExpandedPath)) then
128 begin
129 FindSpecialCharsInPath(ExpandedPath, HasChars);
130 if Ord(Level) <= Ord(ccomlWarning) then
131 begin
132 if Ord(Level) >= Ord(ccomlErrors) then
133 ErrorMsg := SpecialCharsToStr(HasChars * [ccoscSpecialChars, ccoscNewLine])
134 else
135 ErrorMsg := SpecialCharsToStr(HasChars);
136 if ErrorMsg <> '' then
137 begin
138 if IDEMessageDialog(lisCCOWarningCaption, Context + LineEnding + ErrorMsg+Hint,
139 mtWarning, [mbOK, mbCancel]) <> mrOk then
140 exit;
141 end;
142 end;
143 end;
144
145 Result := True;
146 end;
147
148 { TCompilerPathOptionsFrame }
149
TCompilerPathOptionsFrame.Checknull150 function TCompilerPathOptionsFrame.Check: boolean;
151 var
152 NewParsedOutputDir: string;
153
CheckPutSearchPathnull154 function CheckPutSearchPath(
155 const Context, OldExpandedPath, NewExpandedPath: string): boolean;
156 var
157 Level: TCheckCompileOptionsMsgLvl;
158 p: String;
159 begin
160 if OldExpandedPath <> NewExpandedPath then
161 Level := ccomlHints
162 else
163 Level := ccomlErrors;
164
165 // do not complain about missing output directory
166 p:=NewExpandedPath;
167 if NewParsedOutputDir<>'' then
168 p:=RemoveSearchPaths(p,NewParsedOutputDir);
169
170 Result := CheckSearchPath(Context, p, Level, lisHintClickOnShowOptionsToFindOutWhereInheritedPaths);
171 end;
172
173 var
174 OldParsedIncludePath: String;
175 OldParsedLibraryPath: String;
176 OldParsedUnitPath: String;
177 OldParsedSrcPath: String;
178 OldParsedDebugPath: String;
179 OldUnparsedIncludePath: String;
180 OldUnparsedLibraryPath: String;
181 OldUnparsedUnitPath: String;
182 OldUnparsedSrcPath: String;
183 OldUnparsedDebugPath: String;
184 NewParsedIncludePath: String;
185 NewParsedLibraries: String;
186 NewParsedUnitPath: String;
187 NewParsedSrcPath: String;
188 NewParsedDebugPath: String;
189 PathsChanged: boolean;
190
191 procedure GetParsedPaths;
192 begin
193 NewParsedOutputDir:=FCompilerOpts.GetUnitOutPath(False,coptParsed);
194 NewParsedIncludePath:=FCompilerOpts.GetIncludePath(False,coptParsed,false);
195 NewParsedLibraries:=FCompilerOpts.GetLibraryPath(False,coptParsed,false);
196 NewParsedUnitPath:=FCompilerOpts.GetUnitPath(False,coptParsed,false);
197 NewParsedSrcPath:=FCompilerOpts.GetSrcPath(False,coptParsed,false);
198 NewParsedDebugPath:=FCompilerOpts.GetDebugPath(False,coptParsed,false);
199 end;
200
201 var
202 o: TParsedCompilerOptString;
203 Msg: String;
204 begin
205 Result:=false;
206 // Project compiler options have changed if BuildMode was changed by user.
207 if FHasProjectCompilerOpts then
208 FCompilerOpts := Project1.CompilerOptions;
209
210 GetParsedPaths;
211 OldParsedIncludePath := NewParsedIncludePath;
212 OldUnparsedIncludePath := FCompilerOpts.IncludePath;
213 OldParsedLibraryPath := NewParsedLibraries;
214 OldUnparsedLibraryPath := FCompilerOpts.Libraries;
215 OldParsedUnitPath := NewParsedUnitPath;
216 OldUnparsedUnitPath := FCompilerOpts.OtherUnitFiles;
217 OldParsedSrcPath := NewParsedSrcPath;
218 OldUnparsedSrcPath := FCompilerOpts.SrcPath;
219 OldParsedDebugPath := NewParsedDebugPath;
220 OldUnparsedDebugPath := FCompilerOpts.DebugPath;
221
222 try
223 FCompilerOpts.IncludePath := IncludeFilesEdit.Text;
224 FCompilerOpts.Libraries := LibrariesEdit.Text;
225 FCompilerOpts.OtherUnitFiles := OtherUnitsEdit.Text;
226 FCompilerOpts.SrcPath := OtherSourcesEdit.Text;
227 FCompilerOpts.DebugPath := DebugPathEdit.Text;
228 GetParsedPaths;
229
230 if FCompilerOpts.ParsedOpts.HasParsedError then begin
231 o:=FCompilerOpts.ParsedOpts.ParsedErrorOption;
232 case o of
233 pcosBaseDir:
234 Msg:=lisIWonderHowYouDidThatErrorInTheBaseDirectory;
235 pcosUnitPath:
236 Msg:=lisErrorInTheSearchPathForOtherUnitFiles;
237 pcosIncludePath:
238 Msg:=lisErrorInTheSearchPathForIncludeFiles;
239 pcosObjectPath:
240 Msg:=lisErrorInTheSearchPathForObjectFiles;
241 pcosLibraryPath:
242 Msg:=lisErrorInTheSearchPathForLibraries;
243 pcosSrcPath:
244 Msg:=lisErrorInTheSearchPathForOtherSources;
245 pcosLinkerOptions:
246 Msg:=lisErrorInTheCustomLinkerOptionsLinkingPassOptionsToL;
247 pcosCustomOptions:
248 Msg:=lisErrorInTheCustomCompilerOptionsOther;
249 pcosOutputDir:
250 Msg:=lisErrorInTheUnitOutputDirectory;
251 pcosCompilerPath:
252 Msg:=lisErrorInTheCompilerFileName;
253 pcosDebugPath:
254 Msg:=lisErrorInTheDebuggerPathAddition;
255 else
256 Msg:=Format(lisIWonderHowYouDidThatErrorInThe, [EnumToStr(o)]);
257 end;
258 Msg:=Msg+LineEnding+FCompilerOpts.ParsedOpts.ParsedErrorMsg+LineEnding
259 +lisValue3+dbgstr(FCompilerOpts.ParsedOpts.Values[o].UnparsedValue);
260 IDEMessageDialog(lisCCOErrorCaption, Msg, mtError, [mbCancel]);
261 exit;
262 end;
263
264 if not CheckPutSearchPath('include search path', OldParsedIncludePath, NewParsedIncludePath) then
265 Exit;
266 if not CheckPutSearchPath('library search path', OldParsedLibraryPath, NewParsedLibraries) then
267 Exit;
268 if not CheckPutSearchPath('unit search path', OldParsedUnitPath, NewParsedUnitPath) then
269 Exit;
270 if not CheckPutSearchPath('source search path', OldParsedSrcPath, NewParsedSrcPath) then
271 Exit;
272 if not CheckPutSearchPath('debugger search path', OldParsedDebugPath, NewParsedDebugPath) then
273 Exit;
274
275 if not CheckSrcPathInUnitPath(OldParsedSrcPath,NewParsedSrcPath,
276 OldParsedUnitPath,NewParsedUnitPath,PathsChanged)
277 then
278 Exit;
279 if PathsChanged then
280 GetParsedPaths;
281
282 finally
283 FCompilerOpts.IncludePath := OldUnparsedIncludePath;
284 FCompilerOpts.Libraries := OldUnparsedLibraryPath;
285 FCompilerOpts.OtherUnitFiles := OldUnparsedUnitPath;
286 FCompilerOpts.SrcPath := OldUnparsedSrcPath;
287 FCompilerOpts.DebugPath := OldUnparsedDebugPath;
288 end;
289 Result := True;
290 end;
291
TCompilerPathOptionsFrame.GetTitlenull292 function TCompilerPathOptionsFrame.GetTitle: string;
293 begin
294 Result := dlgSearchPaths;
295 end;
296
297 procedure TCompilerPathOptionsFrame.DoShowOptions(Sender: TObject);
298 begin
299 DoSaveSettings(FCompilerOpts);
300 ShowCompilerOptionsDialog(FDialog, FCompilerOpts);
301 end;
302
303 procedure TCompilerPathOptionsFrame.DoCheck(Sender: TObject);
304 begin
305 DoSaveSettings(FCompilerOpts);
306 if Assigned(TestCompilerOptions) then
307 begin
308 btnCheck.Enabled := False;
309 try
310 TestCompilerOptions(FCompilerOpts);
311 finally
312 btnCheck.Enabled := True;
313 end;
314 end;
315 end;
316
317 procedure TCompilerPathOptionsFrame.DoImport(Sender: TObject);
318 begin
319 DoSaveSettings(FCompilerOpts);
320 if (ShowImportCompilerOptionsDialog(FCompilerOpts, FDialog) = mrOK)
321 and Assigned(OnLoadIDEOptions) then
322 OnLoadIDEOptions(Self, FCompilerOpts);
323 end;
324
325 procedure TCompilerPathOptionsFrame.DoExport(Sender: TObject);
326 begin
327 DoSaveSettings(FCompilerOpts);
328 if (ShowExportCompilerOptionsDialog(FCompilerOpts, FDialog) = mrOK)
329 and Assigned(OnSaveIDEOptions) then
330 OnSaveIDEOptions(Self, FCompilerOpts);
331 end;
332
333 procedure TCompilerPathOptionsFrame.DoSaveSettings(AOptions: TAbstractIDEOptions);
334 begin
335 if Assigned(OnSaveIDEOptions) then
336 OnSaveIDEOptions(Self, AOptions);
337 end;
338
339 procedure TCompilerPathOptionsFrame.UpdateTargetFileLabel;
340 begin
341 if ProjTargetFileEdit.Text<>'' then
342 ProjTargetFileLabel.Caption:=lisTargetFileNameO
343 else
344 ProjTargetFileLabel.Caption:=lisTargetFileNameEmptyUseUnitOutputDirectory;
345 end;
346
347 constructor TCompilerPathOptionsFrame.Create(TheOwner: TComponent);
348 begin
349 inherited Create(TheOwner);
350 FCompilerOpts := nil;
351 end;
352
353 procedure TCompilerPathOptionsFrame.ProjTargetFileEditChange(Sender: TObject);
354 begin
355 UpdateTargetFileLabel;
356 end;
357
TCompilerPathOptionsFrame.CheckSrcPathInUnitPathnull358 function TCompilerPathOptionsFrame.CheckSrcPathInUnitPath(OldParsedSrcPath,
359 NewParsedSrcPath, OldParsedUnitPath, NewParsedUnitPath: string; out
360 SrcPathChanged: boolean): boolean;
361 // checks if the SrcPath contains directories of the UnitPath
362 // the SrcPath should only contain directories for the IDE, not for the compiler
363 var
364 p: Integer;
365 CurPath: String;
366 Duplicates: TStringList;
367 i: PtrUInt;
368 OldUnparsedSrcPath: String;
369 NewUnparsedSrcPath: String;
370 j: Integer;
371 BaseDir: String;
372 begin
373 Result:=true;
374 SrcPathChanged:=false;
375 if (OldParsedSrcPath=NewParsedSrcPath)
376 and (OldParsedUnitPath=NewParsedUnitPath) then exit;
377
378 Duplicates:=TStringList.Create;
379 try
380 p:=1;
381 i:=0;
382 BaseDir:=AppendPathDelim(FCompilerOpts.BaseDirectory);
383 repeat
384 CurPath:=GetNextDirectoryInSearchPath(NewParsedSrcPath, p);
385 if (CurPath<>'') and (not IDEMacros.StrHasMacros(CurPath)) and
386 (FilenameIsAbsolute(CurPath)) then
387 begin
388 if (SearchDirectoryInSearchPath(NewParsedUnitPath,CurPath)>0)
389 or (CompareFilenames(BaseDir,AppendPathDelim(CurPath))=0) then
390 Duplicates.AddObject(CurPath,TObject({%H-}Pointer(i)));
391 end;
392 inc(i);
393 until p>length(NewParsedSrcPath);
394
395 if Duplicates.Count>0 then
396 begin
397 debugln(['TCompilerPathOptionsFrame.CheckSrcPathInUnitPath OldParsedSrcPath="',OldParsedSrcPath,'" NewParsedSrcPath="',NewParsedSrcPath,'" OldParsedUnitPath="',OldParsedUnitPath,'" NewParsedUnitPath="',NewParsedUnitPath,'"']);
398 Result:=false;
399 Duplicates.Delimiter:=#13;
400 Duplicates.StrictDelimiter:=true;
401 if IDEQuestionDialog(lisDuplicateSearchPath,
402 Format(lisTheOtherSourcesContainsADirectoryWhichIsAlreadyInT,
403 [LineEnding+LineEnding, Duplicates.DelimitedText]),
404 mtError, [mrCancel,
405 mrYes, lisRemoveThePathsFromOtherSources, 'IsDefault']) = mrYes
406 then begin
407 // remove paths from SrcPath
408 OldUnparsedSrcPath:=FCompilerOpts.SrcPath;
409 NewUnparsedSrcPath:='';
410 i:=0;
411 p:=1;
412 repeat
413 CurPath:=GetNextDirectoryInSearchPath(OldUnparsedSrcPath, p);
414 j:=Duplicates.Count-1;
415 while (j>=0) and (PtrUInt(Duplicates.Objects[j])<>i) do dec(j);
416 if j<0 then
417 begin
418 if NewUnparsedSrcPath<>'' then
419 NewUnparsedSrcPath:=NewUnparsedSrcPath+';';
420 NewUnparsedSrcPath:=NewUnparsedSrcPath+CurPath;
421 end;
422 inc(i);
423 until p>length(OldUnparsedSrcPath);
424 FCompilerOpts.SrcPath:=NewUnparsedSrcPath;
425 OtherSourcesEdit.Text:=FCompilerOpts.SrcPath;
426
427 SrcPathChanged:=true;
428 // do not set Result to true, let's user review the changes
429 end;
430 end;
431 finally
432 Duplicates.Free;
433 end;
434 end;
435
436 procedure TCompilerPathOptionsFrame.PathEditBtnClick(Sender: TObject);
437 begin
438 if Sender is TPathEditorButton then
439 TPathEditorButton(Sender).CurrentPathEditor.BaseDirectory := FCompilerOpts.BaseDirectory;
440 end;
441
PathEditBtnExecutednull442 function TCompilerPathOptionsFrame.PathEditBtnExecuted(Context: String; var NewPath: String): Boolean;
443 var
444 ExpandedPath: string;
445 begin
446 NewPath := FCompilerOpts.ShortenPath(NewPath);
447 ExpandedPath := TrimSearchPath(NewPath, FCompilerOpts.BaseDirectory, true);
448 Result := CheckSearchPath(Context, ExpandedPath, ccomlHints);
449 end;
450
451 procedure TCompilerPathOptionsFrame.FileBrowseBtnClick(Sender: TObject);
452 var
453 OpenDialog: TOpenDialog;
454 DefaultFilename: string;
455 NewFilename: string;
456 begin
457 OpenDialog := TSelectDirectoryDialog.Create(Self);
458 try
459 DefaultFilename := '';
460 if Sender = btnUnitOutputDir then
461 begin
462 OpenDialog.Title := lisUnitOutputDirectory;
463 OpenDialog.Options := OpenDialog.Options + [ofPathMustExist];
464 end
465 else
466 Exit;
467 OpenDialog.Filename := ExtractFilename(DefaultFilename);
468 if DefaultFilename <> '' then
469 OpenDialog.InitialDir := ExtractFilePath(DefaultFilename)
470 else
471 OpenDialog.InitialDir := FCompilerOpts.BaseDirectory;
472 if OpenDialog.Execute then
473 begin
474 NewFilename := TrimFilename(OpenDialog.Filename);
475 NewFilename := FCompilerOpts.ShortenPath(NewFilename);
476 if Sender = btnUnitOutputDir then
477 UnitOutputDirEdit.Text := OpenDialog.Filename;
478 end;
479 finally
480 OpenDialog.Free;
481 end;
482 end;
483
484 procedure TCompilerPathOptionsFrame.Setup(ADialog: TAbstractOptionsEditorDialog);
485
486 function CreateButton(ACaption: String; AKind: TBitBtnKind = bkCustom): TBitBtn;
487 begin
488 Result := ADialog.AddButton;
489 Result.Kind := AKind;
490 Result.Caption := ACaption;
491 end;
492
493 begin
494 FDialog:=ADialog;
495 ProjTargetFileEdit.Text:='';
496 ProjTargetApplyConventionsCheckBox.Caption:=lisApplyConventions;
497 ProjTargetApplyConventionsCheckBox.Hint:=lisApplyConventionsHint;
498
499 OtherUnitsLabel.Caption := dlgOtherUnitFiles;
500 OtherUnitsPathEditBtn := TPathEditorButton.Create(Self);
501 with OtherUnitsPathEditBtn do
502 begin
503 Name := 'OtherUnitsPathEditBtn';
504 Caption := '...';
505 Parent := Self;
506 TabOrder := 1;
507 Anchors := [akRight, akTop, akBottom];
508 AnchorParallel(akTop, 0, OtherUnitsEdit);
509 AnchorParallel(akBottom, 0, OtherUnitsEdit);
510 AnchorParallel(akRight, 0, Self);
511 Width := Height;
512 AssociatedEdit := OtherUnitsEdit;
513 ContextCaption := OtherUnitsLabel.Caption;
514 Templates:='$(LazarusDir)/lcl/units/$(TargetCPU)-$(TargetOS)' +
515 ';$(LazarusDir)/lcl/units/$(TargetCPU)-$(TargetOS)/$(LCLWidgetType)' +
516 ';$(LazarusDir)/components/codetools/units/$(TargetCPU)-$(TargetOS)' +
517 ';$(LazarusDir)/components/custom' +
518 ';$(LazarusDir)/packager/units/$(TargetCPU)-$(TargetOS)';
519 OnClick := @PathEditBtnClick;
520 OnExecuted := @PathEditBtnExecuted;
521 end;
522 OtherUnitsEdit.AnchorToNeighbour(akRight, 0, OtherUnitsPathEditBtn);
523
524 {------------------------------------------------------------}
525
526 IncludeFilesLabel.Caption := dlgCOIncFiles;
527 IncludeFilesPathEditBtn := TPathEditorButton.Create(Self);
528 with IncludeFilesPathEditBtn do
529 begin
530 Name := 'IncludeFilesPathEditBtn';
531 Caption := '...';
532 Parent := Self;
533 TabOrder := 3;
534 Anchors := [akRight, akTop, akBottom];
535 AnchorParallel(akTop, 0, IncludeFilesEdit);
536 AnchorParallel(akBottom, 0, IncludeFilesEdit);
537 AnchorParallel(akRight, 0, Self);
538 Width := Height;
539 AssociatedEdit := IncludeFilesEdit;
540 ContextCaption := IncludeFilesLabel.Caption;
541 Templates := 'include;inc';
542 OnClick := @PathEditBtnClick;
543 OnExecuted := @PathEditBtnExecuted;
544 end;
545 IncludeFilesEdit.AnchorToNeighbour(akRight, 0, IncludeFilesPathEditBtn);
546
547 {------------------------------------------------------------}
548
549 OtherSourcesLabel.Caption := dlgCOSources;
550 OtherSourcesPathEditBtn := TPathEditorButton.Create(Self);
551 with OtherSourcesPathEditBtn do
552 begin
553 Name := 'OtherSourcesPathEditBtn';
554 Caption := '...';
555 Parent := Self;
556 TabOrder := 9;
557 Anchors := [akRight, akTop, akBottom];
558 AnchorParallel(akTop, 0, OtherSourcesEdit);
559 AnchorParallel(akBottom, 0, OtherSourcesEdit);
560 AnchorParallel(akRight, 0, Self);
561 Width := Height;
562 AssociatedEdit := OtherSourcesEdit;
563 ContextCaption := OtherSourcesLabel.Caption;
564 Templates := '$(LazarusDir)/lcl' +
565 ';$(LazarusDir)/lcl/interfaces/$(LCLWidgetType)' +
566 ';$(LazarusDir)/components/synedit' +
567 ';$(LazarusDir)/components/codetools';
568 OnClick := @PathEditBtnClick;
569 OnExecuted := @PathEditBtnExecuted;
570 end;
571 OtherSourcesEdit.AnchorToNeighbour(akRight, 0, OtherSourcesPathEditBtn);
572
573 {------------------------------------------------------------}
574
575 LibrariesLabel.Caption := dlgCOLibraries;
576 LibrariesPathEditBtn := TPathEditorButton.Create(Self);
577 with LibrariesPathEditBtn do
578 begin
579 Name := 'LibrariesPathEditBtn';
580 Caption := '...';
581 Parent := Self;
582 TabOrder := 5;
583 Anchors := [akRight, akTop, akBottom];
584 AnchorParallel(akTop, 0, LibrariesEdit);
585 AnchorParallel(akBottom, 0, LibrariesEdit);
586 AnchorParallel(akRight, 0, Self);
587 Width := Height;
588 AssociatedEdit := LibrariesEdit;
589 ContextCaption := LibrariesLabel.Caption;
590 Templates := '/usr/X11R6/lib;/sw/lib';
591 OnClick := @PathEditBtnClick;
592 OnExecuted := @PathEditBtnExecuted;
593 end;
594 LibrariesEdit.AnchorToNeighbour(akRight, 0, LibrariesPathEditBtn);
595
596 {------------------------------------------------------------}
597
598 UnitOutputDirLabel.Caption := dlgUnitOutp;
599 btnUnitOutputDir := TButton.Create(Self);
600 with btnUnitOutputDir do
601 begin
602 Name := 'btnUnitOutputDir';
603 Caption := '...';
604 Parent := Self;
605 TabOrder := 7;
606 Anchors := [akRight, akTop, akBottom];
607 AnchorParallel(akTop, 0, UnitOutputDirEdit);
608 AnchorParallel(akBottom, 0, UnitOutputDirEdit);
609 AnchorParallel(akRight, 0, Self);
610 Width := Height;
611 OnClick := @FileBrowseBtnClick;
612 end;
613 UnitOutputDirEdit.AnchorToNeighbour(akRight, 0, btnUnitOutputDir);
614
615 {------------------------------------------------------------}
616
617 DebugPathLabel.Caption := dlgCODebugPath;
618 DebugPathEditBtn := TPathEditorButton.Create(Self);
619 with DebugPathEditBtn do
620 begin
621 Name := 'DebugPathEditBtn';
622 Caption := '...';
623 Parent := Self;
624 TabOrder := 13;
625 Anchors := [akRight, akTop, akBottom];
626 AnchorParallel(akTop, 0, DebugPathEdit);
627 AnchorParallel(akBottom, 0, DebugPathEdit);
628 AnchorParallel(akRight, 0, Self);
629 Width := Height;
630 AssociatedEdit := DebugPathEdit;
631 ContextCaption := DebugPathLabel.Caption;
632 Templates := '$(LazarusDir)/lcl/include' +
633 ';$(LazarusDir)/lcl/interfaces/$(LCLWidgetType)' +
634 ';$(LazarusDir)/include';
635 OnClick := @PathEditBtnClick;
636 OnExecuted := @PathEditBtnExecuted;
637 end;
638 DebugPathEdit.AnchorToNeighbour(akRight, 0, DebugPathEditBtn);
639
640 {------------------------------------------------------------}
641
642 // register special buttons in the dialog itself
643 btnShowOptions := CreateButton(dlgCOShowOptions);
644 IDEImages.AssignImage(btnShowOptions, 'menu_compiler_options');
645 btnShowOptions.OnClick := @DoShowOptions;
646 // Check
647 btnCheck := CreateButton(lisCompTest);
648 btnCheck.ModalResult := mrNone;
649 btnCheck.OnClick := @DoCheck;
650 btnCheck.LoadGlyphFromStock(idButtonYes);
651
652 ADialog.AddButtonSeparator;
653
654 // Export
655 btnExport := CreateButton(lisExport);
656 btnExport.OnClick := @DoExport;
657 btnExport.Hint := dlgCOLoadSaveHint;
658 btnExport.LoadGlyphFromStock(idButtonSave);
659 // Import
660 btnLoadSave := CreateButton(lisImport);
661 btnLoadSave.OnClick := @DoImport;
662 btnLoadSave.Hint := dlgCOLoadSaveHint;
663 btnLoadSave.LoadGlyphFromStock(idButtonOpen);
664 if btnLoadSave.Glyph.Empty then
665 IDEImages.AssignImage(btnLoadSave, 'laz_save');
666
667 ADialog.AddButtonSeparator;
668
669 chkUseAsDefault := TCheckBox(ADialog.AddControl(TCheckBox));
670 chkUseAsDefault.Caption := dlgCOSetAsDefault;
671 chkUseAsDefault.ShowHint := True;
672 chkUseAsDefault.Hint := lisWhenEnabledTheCurrentOptionsAreSavedToTheTemplateW;
673 end;
674
675 procedure TCompilerPathOptionsFrame.ReadSettings(AOptions: TAbstractIDEOptions);
676 var
677 ProjOpts: TProjectCompilerOptions;
678 begin
679 if not (AOptions is TBaseCompilerOptions) then exit;
680 FCompilerOpts := TBaseCompilerOptions(AOptions);
681
682 if AOptions is TProjectCompilerOptions then
683 begin
684 ProjOpts:=TProjectCompilerOptions(AOptions);
685 FHasProjectCompilerOpts:=True;
686 ProjTargetFileEdit.Visible:=true;
687 ProjTargetFileLabel.Visible:=true;
688 ProjTargetFileEdit.Text:=ProjOpts.TargetFilename;
689 ProjTargetApplyConventionsCheckBox.Checked:=ProjOpts.TargetFilenameApplyConventions;
690 ProjTargetApplyConventionsCheckBox.Visible:=true;
691 UpdateTargetFileLabel;
692 end else begin
693 FHasProjectCompilerOpts:=False;
694 ProjTargetFileEdit.Visible:=false;
695 ProjTargetFileLabel.Visible:=false;
696 ProjTargetApplyConventionsCheckBox.Visible:=false;
697 end;
698
699 SetPathTextAndHint(FCompilerOpts.OtherUnitFiles, OtherUnitsEdit);
700 SetPathTextAndHint(FCompilerOpts.IncludePath, IncludeFilesEdit);
701 SetPathTextAndHint(FCompilerOpts.Libraries, LibrariesEdit);
702 SetPathTextAndHint(FCompilerOpts.SrcPath, OtherSourcesEdit);
703 UnitOutputDirEdit.Text := FCompilerOpts.UnitOutputDirectory;
704 SetPathTextAndHint(FCompilerOpts.DebugPath, DebugPathEdit);
705
706 chkUseAsDefault.Visible := FCompilerOpts.CanBeDefaulForProject;
707 end;
708
709 procedure TCompilerPathOptionsFrame.WriteSettings(AOptions: TAbstractIDEOptions);
710 var
711 ProjCompOpts: TProjectCompilerOptions;
712 begin
713 if AOptions is TProjectCompilerOptions then begin
714 ProjCompOpts:=TProjectCompilerOptions(AOptions);
715 ProjCompOpts.TargetFilename:=ProjTargetFileEdit.Text;
716 ProjCompOpts.TargetFilenameApplyConventions:=ProjTargetApplyConventionsCheckBox.Checked;
717 ProjCompOpts.LazProject.UseAsDefault := chkUseAsDefault.Checked;
718 end;
719
720 with AOptions as TBaseCompilerOptions do
721 begin
722 OtherUnitFiles := OtherUnitsEdit.Text;
723 IncludePath := IncludeFilesEdit.Text;
724 Libraries := LibrariesEdit.Text;
725 SrcPath := OtherSourcesEdit.Text;
726 UnitOutputDirectory := UnitOutputDirEdit.Text;
727 DebugPath := DebugPathEdit.Text;
728 end;
729 end;
730
731 class function TCompilerPathOptionsFrame.SupportedOptionsClass: TAbstractIDEOptionsClass;
732 begin
733 Result := TBaseCompilerOptions;
734 end;
735
736 initialization
737 RegisterIDEOptionsEditor(GroupCompiler, TCompilerPathOptionsFrame,
738 CompilerOptionsSearchPaths);
739 RegisterIDEOptionsEditor(GroupPkgCompiler, TCompilerPathOptionsFrame,
740 CompilerOptionsSearchPaths);
741
742 end.
743
744