43
Classes, SysUtils, LCLProc, Forms, Controls, Buttons, Dialogs, FileUtil,
45
LazarusIDEStrConsts, LazConf, EnvironmentOpts, IDEProcs;
43
Classes, SysUtils, contnrs, LCLProc, Forms, Controls, Buttons, Dialogs,
44
FileUtil, Laz2_XMLCfg, lazutf8classes, Graphics, ComCtrls, ExtCtrls, StdCtrls,
45
DefineTemplates, CodeToolManager,
47
TransferMacros, LazarusIDEStrConsts, LazConf, EnvironmentOpts, IDEProcs,
47
procedure SetupCompilerFilename(var InteractiveSetup: boolean);
48
procedure SetupFPCSourceDirectory(var InteractiveSetup: boolean);
49
procedure SetupLazarusDirectory(var InteractiveSetup: boolean);
51
TSDFilenameQuality = (
53
sddqWrongMinorVersion,
61
Filename: string; // macros resolved, trimmed, expanded
62
Caption: string; // filename with macros
64
Quality: TSDFilenameQuality;
73
{ TInitialSetupDialog }
75
TInitialSetupDialog = class(TForm)
77
CompilerBrowseButton: TButton;
78
CompilerComboBox: TComboBox;
79
CompilerLabel: TLabel;
81
FPCSrcDirBrowseButton: TButton;
82
FPCSrcDirComboBox: TComboBox;
83
FPCSrcDirLabel: TLabel;
85
ImageList1: TImageList;
86
LazDirBrowseButton: TButton;
88
LazDirComboBox: TComboBox;
90
PropertiesPageControl: TPageControl;
91
PropertiesTreeView: TTreeView;
93
StartIDEBitBtn: TBitBtn;
94
LazarusTabSheet: TTabSheet;
95
CompilerTabSheet: TTabSheet;
96
FPCSourcesTabSheet: TTabSheet;
97
WelcomePaintBox: TPaintBox;
98
procedure CompilerBrowseButtonClick(Sender: TObject);
99
procedure CompilerComboBoxChange(Sender: TObject);
100
procedure FormCreate(Sender: TObject);
101
procedure FormDestroy(Sender: TObject);
102
procedure FPCSrcDirBrowseButtonClick(Sender: TObject);
103
procedure FPCSrcDirComboBoxChange(Sender: TObject);
104
procedure LazDirBrowseButtonClick(Sender: TObject);
105
procedure LazDirComboBoxChange(Sender: TObject);
106
procedure OnAppActivate(Sender: TObject);
107
procedure PropertiesPageControlChange(Sender: TObject);
108
procedure PropertiesTreeViewSelectionChanged(Sender: TObject);
109
procedure StartIDEBitBtnClick(Sender: TObject);
110
procedure WelcomePaintBoxPaint(Sender: TObject);
111
procedure OnIdle(Sender: TObject; var {%H-}Done: Boolean);
113
FLazarusDirChanged: boolean;
114
fCompilerFilenameChanged: boolean;
115
FLastParsedLazDir: string;
116
fLastParsedCompiler: string;
117
fLastParsedFPCSrcDir: string;
118
FIdleConnected: boolean;
120
ImgIDWarning: LongInt;
121
FHeadGraphic: TPortableNetworkGraphic;
122
FSelectingPage: boolean;
123
FCandidates: array[TSDFilenameType] of TObjectList; // list of TSDFileInfo
124
procedure SelectPage(const NodeText: string);
125
function SelectDirectory(aTitle: string): string;
126
procedure UpdateLazarusDirCandidates;
127
procedure UpdateCompilerFilenameCandidates;
128
procedure UpdateFPCSrcDirCandidates;
129
procedure FillComboboxWithFileInfoList(ABox: TComboBox; List: TObjectList;
130
ItemIndex: integer = 0);
131
procedure SetIdleConnected(const AValue: boolean);
132
procedure UpdateLazDirNote;
133
procedure UpdateCompilerNote;
134
procedure UpdateFPCSrcDirNote;
135
function FirstErrorNode: TTreeNode;
136
function GetFPCVer: string;
137
function GetFirstCandidate(Candidates: TObjectList;
138
MinQuality: TSDFilenameQuality = sddqCompatible): TSDFileInfo;
139
function QualityToImgIndex(Quality: TSDFilenameQuality): integer;
141
TVNodeLazarus: TTreeNode;
142
TVNodeCompiler: TTreeNode;
143
TVNodeFPCSources: TTreeNode;
145
property IdleConnected: boolean read FIdleConnected write SetIdleConnected;
148
function ShowInitialSetupDialog: TModalResult;
150
function CheckLazarusDirectoryQuality(ADirectory: string;
151
out Note: string): TSDFilenameQuality;
152
function SearchLazarusDirectoryCandidates(StopIfFits: boolean): TObjectList;
153
procedure SetupLazarusDirectory;
155
function CheckCompilerQuality(AFilename: string;
156
out Note: string; TestSrcFilename: string): TSDFilenameQuality;
157
function SearchCompilerCandidates(StopIfFits: boolean;
158
const TestSrcFilename: string): TObjectList;
159
procedure SetupCompilerFilename;
161
function CheckFPCSrcDirQuality(ADirectory: string;
162
out Note: string; FPCVer: string): TSDFilenameQuality;
163
function SearchFPCSrcDirCandidates(StopIfFits: boolean;
164
const FPCVer: string): TObjectList;
165
procedure SetupFPCSrcDir(FPCVer: string);
167
function CheckMakeExeQuality(AFilename: string;
168
out Note: string): TSDFilenameQuality;
169
function SearchMakeExeCandidates(StopIfFits: boolean): TObjectList;
170
procedure SetupMakeExe;
172
function GetValueFromPrimaryConfig(OptionFilename, Path: string): string;
51
173
function GetValueFromSecondaryConfig(OptionFilename, Path: string): string;
174
function GetValueFromIDEConfig(OptionFilename, Path: string): string;
55
procedure SetupCompilerFilename(var InteractiveSetup: boolean);
57
DefaultCompPath: String;
58
CurCompilerFilename: String;
61
CurCompilerFilename:=EnvironmentOptions.GetCompilerFilename;
62
if CurCompilerFilename='' then
63
CurCompilerFilename:=FindDefaultCompilerPath;
64
if not FileIsExecutable(CurCompilerFilename) then
65
CurCompilerFilename:=GetValueFromSecondaryConfig(EnvOptsConfFileName,
66
'EnvironmentOptions/CompilerFilename/Value');
67
if not FileIsExecutable(CurCompilerFilename) then begin
68
if not InteractiveSetup then exit;
69
if CurCompilerFilename='' then begin
70
MessageDlg(lisFreePascalCompilerNotFound,
71
Format(lisTheFreePascalCompilerFilenameWasNotFoundItIsRecomm, [
72
GetDefaultCompilerFilename, #13]),
73
mtWarning,[mbIgnore],0);
75
DefaultCompPath:=FindDefaultCompilerPath;
76
if CompareFilenames(DefaultCompPath,CurCompilerFilename)<>0 then begin
77
r:=MessageDlg(lisInvalidCompilerFilename,
78
Format(lisTheCurrentCompilerFilenameIsNotAValidExecutableCho, ['"',
79
CurCompilerFilename, '"', #13, #13, '"', DefaultCompPath, '"', #13]
81
mtWarning,[mbOk,mbIgnore],0);
83
CurCompilerFilename:=DefaultCompPath;
85
MessageDlg(lisInvalidCompilerFilename,
86
Format(lisTheCurrentCompilerFilenameIsNotAValidExecutablePlease, ['"',
87
CurCompilerFilename, '"', #13, #13]),
88
mtWarning,[mbIgnore],0);
92
EnvironmentOptions.CompilerFilename:=CurCompilerFilename;
95
procedure SetupFPCSourceDirectory(var InteractiveSetup: boolean);
98
DefaultFPCSrcDir: String;
102
CurFPCSrcDir:=EnvironmentOptions.GetFPCSourceDirectory;
104
if CurFPCSrcDir='' then begin
105
CurFPCSrcDir:=FindDefaultFPCSrcDirectory;
108
if not DirectoryExistsUTF8(CurFPCSrcDir) then
110
CurFPCSrcDir:=GetValueFromSecondaryConfig(EnvOptsConfFileName,
111
'EnvironmentOptions/FPCSourceDirectory/Value');
114
if not CheckFPCSourceDir(CurFPCSrcDir) then begin
115
if (not InteractiveSetup)
116
or (not FileIsExecutable(EnvironmentOptions.GetCompilerFilename)) then
118
if CurFPCSrcDir='' then begin
119
MessageDlg(lisFreePascalSourcesNotFound,
120
Format(lisTheFreePascalSourceDirectoryWasNotFoundSomeCodeFun, [#13,
122
mtWarning,[mbIgnore],0);
124
DefaultFPCSrcDir:=FindDefaultFPCSrcDirectory;
125
if CompareFilenames(DefaultFPCSrcDir,CurFPCSrcDir)<>0 then begin
126
r:=MessageDlg(lisInvalidFreePascalSourceDirectory,
127
Format(lisTheCurrentFreePascalSourceDirectoryDoesNotLookCorr, ['"',
128
CurFPCSrcDir, '"', #13, #13, '"', DefaultFPCSrcDir, '"', #13]),
129
mtWarning,[mbOk,mbIgnore],0);
131
CurFPCSrcDir:=DefaultFPCSrcDir;
182
TSetupMacros = class(TTransferMacroList)
184
procedure DoSubstitution({%H-}TheMacro: TTransferMacro; const MacroName: string;
185
var s: string; const {%H-}Data: PtrInt; var Handled, {%H-}Abort: boolean;
186
{%H-}Depth: integer); override;
192
function CaptionInSDFileList(aCaption: string; SDFileList: TObjectList): boolean;
197
if SDFileList=nil then exit;
198
for i:=0 to SDFileList.Count-1 do
199
if CompareFilenames(aCaption,TSDFileInfo(SDFileList[i]).Caption)=0 then
203
function CheckLazarusDirectoryQuality(ADirectory: string;
204
out Note: string): TSDFilenameQuality;
206
function SubDirExists(SubDir: string; var q: TSDFilenameQuality): boolean;
208
SubDir:=SetDirSeparators(SubDir);
209
if DirPathExistsCached(ADirectory+SubDir) then exit(true);
211
Note:=Format(lisDirectoryNotFound2, [SubDir]);
215
function SubFileExists(SubFile: string; var q: TSDFilenameQuality): boolean;
217
SubFile:=SetDirSeparators(SubFile);
218
if FileExistsCached(ADirectory+SubFile) then exit(true);
220
Note:=Format(lisFileNotFound3, [SubFile]);
226
VersionIncFile: String;
230
ADirectory:=TrimFilename(ADirectory);
231
if not DirPathExistsCached(ADirectory) then
233
Note:=lisISDDirectoryNotFound;
236
ADirectory:=AppendPathDelim(ADirectory);
237
if not SubDirExists('lcl',Result) then exit;
238
if not SubDirExists('packager/globallinks',Result) then exit;
239
if not SubDirExists('ide',Result) then exit;
240
if not SubDirExists('components',Result) then exit;
241
if not SubDirExists('ideintf',Result) then exit;
242
if not SubFileExists('ide/lazarus.lpi',Result) then exit;
243
VersionIncFile:=SetDirSeparators('ide/version.inc');
244
if not SubFileExists(VersionIncFile,Result) then exit;
245
sl:=TStringListUTF8.Create;
248
sl.LoadFromFile(ADirectory+VersionIncFile);
249
if (sl.Count=0) or (sl[0]='') or (sl[0][1]<>'''') then
251
Note:=Format(lisInvalidVersionIn, [VersionIncFile]);
254
Version:=copy(sl[0],2,length(sl[0])-2);
255
if Version<>LazarusVersionStr then
257
Note:=Format(lisWrongVersionIn, [VersionIncFile, Version]);
258
Result:=sddqWrongVersion;
262
Result:=sddqCompatible;
264
on E: Exception do begin
265
Note:=Format(lisUnableToLoadFile2, [VersionIncFile, E.Message]);
274
function SearchLazarusDirectoryCandidates(StopIfFits: boolean): TObjectList;
276
function CheckDir(Dir: string; var List: TObjectList): boolean;
282
if Dir='' then Dir:='.';
283
DoDirSeparators(Dir);
284
Dir:=ChompPathDelim(Dir);
285
// check if already checked
286
if CaptionInSDFileList(Dir,List) then exit;
287
EnvironmentOptions.LazarusDirectory:=Dir;
288
RealDir:=ChompPathDelim(EnvironmentOptions.GetParsedLazarusDirectory);
289
debugln(['SearchLazarusDirectoryCandidates Value=',Dir,' File=',RealDir]);
291
if not DirPathExistsCached(RealDir) then exit;
292
// add to list and check quality
293
Item:=TSDFileInfo.Create;
294
Item.Filename:=RealDir;
295
Item.Quality:=CheckLazarusDirectoryQuality(RealDir,Item.Note);
298
List:=TObjectList.create(true);
300
Result:=(Item.Quality=sddqCompatible) and StopIfFits;
303
function CheckViaExe(Filename: string; var List: TObjectList): boolean;
306
Filename:=FindDefaultExecutablePath(Filename);
307
if Filename='' then exit;
308
Filename:=ReadAllLinks(Filename,false);
309
if Filename='' then exit;
310
Result:=CheckDir(ExtractFilePath(ExpandFileNameUTF8(Filename)),List);
318
OldLazarusDir: String;
322
OldLazarusDir:=EnvironmentOptions.LazarusDirectory;
324
// first check the value in the options
325
if CheckDir(EnvironmentOptions.LazarusDirectory,Result) then exit;
327
// then check the directory of the executable
328
Dir:=ProgramDirectory(true);
329
if CheckDir(Dir,Result) then exit;
330
ResolvedDir:=ReadAllLinks(Dir,false);
331
if (ResolvedDir<>Dir) and (CheckDir(ResolvedDir,Result)) then exit;
333
// check the primary options
334
Dir:=GetValueFromPrimaryConfig(EnvOptsConfFileName,
335
'EnvironmentOptions/LazarusDirectory/Value');
336
if CheckDir(Dir,Result) then exit;
338
// check the secondary options
339
Dir:=GetValueFromSecondaryConfig(EnvOptsConfFileName,
340
'EnvironmentOptions/LazarusDirectory/Value');
341
if CheckDir(Dir,Result) then exit;
343
// check common directories
344
Dirs:=GetDefaultLazarusSrcDirectories;
346
for i:=0 to Dirs.Count-1 do
347
if CheckDir(Dirs[i],Result) then exit;
353
Dirs:=EnvironmentOptions.LazarusDirHistory;
355
for i:=0 to Dirs.Count-1 do
356
if CheckDir(Dirs[i],Result) then exit;
358
// search lazarus-ide and lazarus in PATH, then follow the links,
359
// which will lead to the lazarus directory
360
if CheckViaExe('lazarus-ide'+GetExecutableExt,Result) then exit;
361
if CheckViaExe('lazarus'+GetExecutableExt,Result) then exit;
364
EnvironmentOptions.LazarusDirectory:=OldLazarusDir;
368
procedure SetupLazarusDirectory;
372
Quality: TSDFilenameQuality;
373
BestDir: TSDFileInfo;
376
Dir:=EnvironmentOptions.GetParsedLazarusDirectory;
377
Quality:=CheckLazarusDirectoryQuality(Dir,Note);
378
if Quality<>sddqInvalid then exit;
379
// bad lazarus directory => searching a good one
380
dbgout('SetupLazarusDirectory:');
381
if EnvironmentOptions.LazarusDirectory<>'' then
383
dbgout(' The Lazarus directory "',EnvironmentOptions.LazarusDirectory,'"');
384
if EnvironmentOptions.LazarusDirectory<>Dir then
385
dbgout(' => "',Dir,'"');
386
dbgout(' is invalid (Error: ',Note,')');
387
debugln(' Searching a proper one ...');
389
debugln(' Searching ...');
391
List:=SearchLazarusDirectoryCandidates(true);
395
BestDir:=TSDFileInfo(List[List.Count-1]);
396
if (BestDir=nil) or (BestDir.Quality=sddqInvalid) then begin
397
debugln(['SetupLazarusDirectory: no proper Lazarus directory found.']);
400
EnvironmentOptions.LazarusDirectory:=BestDir.Filename;
401
debugln(['SetupLazarusDirectory: using ',EnvironmentOptions.LazarusDirectory]);
407
function CheckCompilerQuality(AFilename: string; out Note: string;
408
TestSrcFilename: string): TSDFilenameQuality;
410
CfgCache: TFPCTargetConfigCache;
412
ShortFilename: String;
415
AFilename:=TrimFilename(AFilename);
416
if not FileExistsCached(AFilename) then
418
Note:=lisFileNotFound4;
421
if DirPathExistsCached(AFilename) then
423
Note:=lisFileIsDirectory;
426
if not FileIsExecutableCached(AFilename) then
428
Note:=lisFileIsNotAnExecutable;
432
// do not execute unusual exe files
433
ShortFilename:=ExtractFileNameOnly(AFilename);
434
if (CompareFilenames(ShortFilename,'fpc')<>0)
435
and (CompareFilenames(copy(ShortFilename,1,3),'ppc')<>0)
437
Note:=lisUnusualCompilerFileNameUsuallyItStartsWithFpcPpcOr;
438
exit(sddqIncomplete);
441
if TestSrcFilename<>'' then
443
CfgCache:=CodeToolBoss.FPCDefinesCache.ConfigCaches.Find(
444
AFilename,'','','',true);
445
if CfgCache.NeedsUpdate then
446
CfgCache.Update(TestSrcFilename);
447
i:=CfgCache.IndexOfUsedCfgFile;
450
Note:=lisFpcCfgIsMissing;
453
if not CfgCache.HasPPUs then
455
Note:=lisSystemPpuNotFoundCheckYourFpcCfg;
458
if CompareFileExt(CfgCache.Units['classes'],'ppu',false)<>0 then
460
Note:=lisClassesPpuNotFoundCheckYourFpcCfg;
466
Result:=sddqCompatible;
469
function SearchCompilerCandidates(StopIfFits: boolean;
470
const TestSrcFilename: string): TObjectList;
472
ShortCompFile: String;
474
function CheckFile(AFilename: string; var List: TObjectList): boolean;
477
RealFilename: String;
480
if AFilename='' then exit;
481
DoDirSeparators(AFilename);
482
// check if already checked
483
if CaptionInSDFileList(AFilename,List) then exit;
484
EnvironmentOptions.CompilerFilename:=AFilename;
485
RealFilename:=EnvironmentOptions.GetParsedCompilerFilename;
486
debugln(['SearchCompilerCandidates Value=',AFilename,' File=',RealFilename]);
487
if RealFilename='' then exit;
489
if not FileExistsCached(RealFilename) then exit;
490
// add to list and check quality
491
Item:=TSDFileInfo.Create;
492
Item.Filename:=RealFilename;
493
Item.Quality:=CheckCompilerQuality(RealFilename,Item.Note,TestSrcFilename);
494
Item.Caption:=AFilename;
496
List:=TObjectList.create(true);
498
Result:=(Item.Quality=sddqCompatible) and StopIfFits;
501
function CheckSubDirs(ADir: string; var List: TObjectList): boolean;
502
// search for ADir\bin\i386-win32\fpc.exe
503
// and for ADir\*\bin\i386-win32\fpc.exe
505
FileInfo: TSearchRec;
509
ADir:=AppendPathDelim(TrimFilename(ExpandFileNameUTF8(TrimFilename(ADir))));
510
SubFile:='bin/$(TargetCPU)-$(TargetOS)/'+ShortCompFile;
511
if CheckFile(ADir+SubFile,List) then
514
if FindFirstUTF8(ADir+GetAllFilesMask,faAnyFile,FileInfo)=0 then begin
516
// check if special file
517
if (FileInfo.Name='.') or (FileInfo.Name='..') or (FileInfo.Name='') then
519
if ((FileInfo.Attr and faDirectory)>0)
520
and CheckFile(ADir+FileInfo.Name+PathDelim+SubFile,List) then
522
until FindNextUTF8(FileInfo)<>0;
525
FindCloseUTF8(FileInfo);
536
OldCompilerFilename: String;
540
OldCompilerFilename:=EnvironmentOptions.CompilerFilename;
542
// check current setting
543
if CheckFile(EnvironmentOptions.CompilerFilename,Result) then exit;
545
// check the primary options
546
AFilename:=GetValueFromPrimaryConfig(EnvOptsConfFileName,
547
'EnvironmentOptions/CompilerFilename/Value');
548
if CheckFile(AFilename,Result) then exit;
550
// check the secondary options
551
AFilename:=GetValueFromSecondaryConfig(EnvOptsConfFileName,
552
'EnvironmentOptions/CompilerFilename/Value');
553
if CheckFile(AFilename,Result) then exit;
556
if CheckFile(FindDefaultCompilerPath,Result) then exit;
559
Files:=EnvironmentOptions.CompilerFileHistory;
561
for i:=0 to Files.Count-1 do
562
if CheckFile(Files[i],Result) then exit;
564
// check paths with versions
565
ShortCompFile:=GetDefaultCompilerFilename;
567
// check $(LazarusDir)\fpc\bin\i386-win32\fpc.exe
568
if CheckFile(SetDirSeparators('$(LazarusDir)/fpc/bin/$(TargetCPU)-$(TargetOS)/')+ShortCompFile,Result)
571
// check common directories
572
Files:=TStringList.Create;
574
GetDefaultCompilerFilenames(Files);
575
for i:=0 to Files.Count-1 do
576
if CheckFile(Files[i],Result) then exit;
581
if (GetDefaultSrcOSForTargetOS(GetCompiledTargetOS)='win') then begin
582
// Windows has some special places
583
SysDrive:=GetEnvironmentVariableUTF8('SYSTEMDRIVE');
584
if SysDrive='' then SysDrive:='C:';
585
SysDrive:=AppendPathDelim(SysDrive);
586
// %SYSTEMDRIVE%\fpc\
587
if CheckSubDirs(SysDrive+'FPC',Result) then exit;
589
if CheckSubDirs(SysDrive+'pp',Result) then exit;
590
// %PROGRAMFILES%\FPC\*
591
ProgDir:=AppendPathDelim(GetEnvironmentVariableUTF8('PROGRAMFILES'));
593
and CheckSubDirs(ProgDir+'FPC',Result) then exit;
597
EnvironmentOptions.CompilerFilename:=OldCompilerFilename;
601
procedure SetupCompilerFilename;
605
Quality: TSDFilenameQuality;
606
BestDir: TSDFileInfo;
609
Filename:=EnvironmentOptions.GetParsedCompilerFilename;
610
Quality:=CheckCompilerQuality(Filename,Note,'');
611
if Quality<>sddqInvalid then exit;
613
dbgout('SetupCompilerFilename:');
614
if EnvironmentOptions.CompilerFilename<>'' then
616
dbgout(' The compiler path "',EnvironmentOptions.CompilerFilename,'"');
617
if EnvironmentOptions.CompilerFilename<>Filename then
618
dbgout(' => "',Filename,'"');
619
dbgout(' is invalid (Error: ',Note,')');
620
debugln(' Searching a proper one ...');
622
debugln(' Searching compiler ...');
624
List:=SearchCompilerCandidates(true,CodeToolBoss.FPCDefinesCache.TestFilename);
628
BestDir:=TSDFileInfo(List[List.Count-1]);
629
if (BestDir=nil) or (BestDir.Quality=sddqInvalid) then begin
630
debugln(['SetupCompilerFilename: no proper compiler found.']);
633
EnvironmentOptions.CompilerFilename:=BestDir.Filename;
634
debugln(['SetupCompilerFilename: using ',EnvironmentOptions.CompilerFilename]);
640
function CheckFPCSrcDirQuality(ADirectory: string; out Note: string;
641
FPCVer: string): TSDFilenameQuality;
643
function SubDirExists(SubDir: string; var q: TSDFilenameQuality): boolean;
645
SubDir:=SetDirSeparators(SubDir);
646
if DirPathExistsCached(ADirectory+SubDir) then exit(true);
648
Note:=Format(lisDirectoryNotFound2, [SubDir]);
652
function SubFileExists(SubFile: string; var q: TSDFilenameQuality): boolean;
654
SubFile:=SetDirSeparators(SubFile);
655
if FileExistsCached(ADirectory+SubFile) then exit(true);
657
Note:=Format(lisFileNotFound3, [SubFile]);
672
ADirectory:=TrimFilename(ADirectory);
673
if not DirPathExistsCached(ADirectory) then
675
Note:=lisISDDirectoryNotFound;
678
ADirectory:=AppendPathDelim(ADirectory);
679
if not SubDirExists('rtl',Result) then exit;
680
if not SubDirExists('packages',Result) then exit;
681
if not SubFileExists('rtl/linux/system.pp',Result) then exit;
685
VersionFile:=ADirectory+'compiler'+PathDelim+'version.pas';
686
if FileExistsCached(VersionFile) then
688
sl:=TStringListUTF8.Create;
691
sl.LoadFromFile(VersionFile);
692
for i:=0 to sl.Count-1 do
694
if REMatches(sl[i],' version_nr *= *''([0-9]+)''','I') then
696
else if REMatches(sl[i],' release_nr *= *''([0-9]+)''','I') then
698
else if REMatches(sl[i],' patch_nr *= *''([0-9]+)''','I') then begin
703
SrcVer:=VersionNr+'.'+ReleaseNr+'.'+PatchNr;
704
if SrcVer<>FPCVer then
706
Note:=Format(lisFoundVersionExpected, [SrcVer, FPCVer]);
707
SrcVer:=VersionNr+'.'+ReleaseNr+'.';
708
if LeftStr(FPCVer,length(SrcVer))=SrcVer then
709
Result:=sddqWrongMinorVersion
711
Result:=sddqWrongVersion;
135
MessageDlg(lisInvalidFreePascalSourceDirectory,
136
Format(lisTheCurrentFreePascalSourceDirectoryDoesNotLookCorr2, ['"',
137
CurFPCSrcDir, '"', #13, #13]),
138
mtWarning,[mbIgnore],0);
143
EnvironmentOptions.FPCSourceDirectory:=CurFPCSrcDir;
146
procedure SetupLazarusDirectory(var InteractiveSetup: boolean);
149
DefaultLazDir: String;
152
CurLazDir:=EnvironmentOptions.LazarusDirectory;
153
if CurLazDir='' then begin
154
CurLazDir:=ProgramDirectory(true);
155
if not CheckLazarusDirectory(CurLazDir) then
156
CurLazDir:=FindDefaultLazarusSrcDirectory;
158
if not CheckLazarusDirectory(CurLazDir) then
159
CurLazDir:=GetValueFromSecondaryConfig(EnvOptsConfFileName,
160
'EnvironmentOptions/LazarusDirectory/Value');
161
if not CheckLazarusDirectory(CurLazDir) then begin
162
if not InteractiveSetup then exit;
163
if CurLazDir='' then begin
164
MessageDlg(lisLazarusDirectoryNotFound,
165
Format(lisTheLazarusDirectoryWasNotFoundYouWillNotBeAbleToCr, [#13, #13]
167
mtWarning,[mbIgnore],0);
169
DefaultLazDir:=ProgramDirectory(true);
170
if CompareFilenames(DefaultLazDir,CurLazDir)<>0 then begin
171
r:=MessageDlg(lisLazarusDirectoryNotFound,
172
Format(lisTheCurrentLazarusDirectoryDoesNotLookCorrectWithou, ['"',
173
CurLazDir, '"', #13, #13, #13, '"', DefaultLazDir, '"', #13]),
174
mtWarning,[mbOk,mbIgnore],0);
176
CurLazDir:=DefaultLazDir;
178
MessageDlg(lisLazarusDirectoryNotFound,
179
Format(lisTheCurrentLazarusDirectoryDoesNotLookCorrectWithou2, ['"',
180
CurLazDir, '"', #13, #13, #13]),
181
mtWarning,[mbIgnore],0);
185
EnvironmentOptions.LazarusDirectory:=CurLazDir;
722
Result:=sddqCompatible;
725
function SearchFPCSrcDirCandidates(StopIfFits: boolean;
726
const FPCVer: string): TObjectList;
728
function Check(Dir: string; var List: TObjectList): boolean;
734
DoDirSeparators(Dir);
735
Dir:=ChompPathDelim(Dir);
737
// check if already checked
738
if CaptionInSDFileList(Dir,List) then exit;
739
EnvironmentOptions.FPCSourceDirectory:=Dir;
740
RealDir:=EnvironmentOptions.GetParsedFPCSourceDirectory;
741
debugln(['SearchFPCSrcDirCandidates Value=',Dir,' File=',RealDir]);
742
if RealDir='' then exit;
744
if not DirPathExistsCached(RealDir) then exit;
745
// add to list and check quality
746
Item:=TSDFileInfo.Create;
747
Item.Filename:=RealDir;
748
Item.Quality:=CheckFPCSrcDirQuality(RealDir,Item.Note,FPCVer);
751
List:=TObjectList.create(true);
753
Result:=(Item.Quality=sddqCompatible) and StopIfFits;
760
OldFPCSrcDir: String;
764
OldFPCSrcDir:=EnvironmentOptions.FPCSourceDirectory;
766
// check current setting
767
if Check(EnvironmentOptions.FPCSourceDirectory,Result) then exit;
769
// check the primary options
770
AFilename:=GetValueFromPrimaryConfig(EnvOptsConfFileName,
771
'EnvironmentOptions/FPCSourceDirectory/Value');
772
if Check(AFilename,Result) then exit;
774
// check the secondary options
775
AFilename:=GetValueFromSecondaryConfig(EnvOptsConfFileName,
776
'EnvironmentOptions/FPCSourceDirectory/Value');
777
if Check(AFilename,Result) then exit;
780
Dirs:=EnvironmentOptions.FPCSourceDirHistory;
782
for i:=0 to Dirs.Count-1 do
783
if Check(Dirs[i],Result) then exit;
785
// $(LazarusDir)/fpc/$(FPCVer)/source
786
if Check(SetDirSeparators('$(LazarusDir)/fpc/$(FPCVer)/source'),Result) then
789
// check relative to fpc.exe
790
if Check(SetDirSeparators('$Path($(CompPath))/../../source'),Result) then
793
// check common directories
794
Dirs:=GetDefaultFPCSrcDirectories;
797
for i:=0 to Dirs.Count-1 do
798
if Check(Dirs[i],Result) then exit;
803
EnvironmentOptions.FPCSourceDirectory:=OldFPCSrcDir;
807
procedure SetupFPCSrcDir(FPCVer: string);
811
Quality: TSDFilenameQuality;
812
BestDir: TSDFileInfo;
815
Dir:=EnvironmentOptions.GetParsedFPCSourceDirectory;
816
Quality:=CheckFPCSrcDirQuality(Dir,Note,FPCVer);
817
if Quality<>sddqInvalid then exit;
818
// bad fpc src directory => searching a good one
819
dbgout('SetupFPCSourceDirectory:');
820
if EnvironmentOptions.FPCSourceDirectory<>'' then
822
dbgout(' The FPC source directory "',EnvironmentOptions.FPCSourceDirectory,'"');
823
if EnvironmentOptions.FPCSourceDirectory<>Dir then
824
dbgout(' => "',Dir,'"');
825
dbgout(' is invalid (Error: ',Note,')');
826
debugln(' Searching a proper one ...');
828
debugln(' Searching ...');
830
List:=SearchFPCSrcDirCandidates(true,FPCVer);
834
BestDir:=TSDFileInfo(List[List.Count-1]);
835
if (BestDir=nil) or (BestDir.Quality=sddqInvalid) then begin
836
debugln(['SetupFPCSourceDirectory: no proper FPC source directory found.']);
839
EnvironmentOptions.FPCSourceDirectory:=BestDir.Filename;
840
debugln(['SetupFPCSourceDirectory: using ',EnvironmentOptions.FPCSourceDirectory]);
846
function CheckMakeExeQuality(AFilename: string; out Note: string
847
): TSDFilenameQuality;
850
AFilename:=TrimFilename(AFilename);
851
if not FileExistsCached(AFilename) then
853
Note:=lisFileNotFound4;
856
if DirPathExistsCached(AFilename) then
858
Note:=lisFileIsDirectory;
861
if not FileIsExecutableCached(AFilename) then
863
Note:=lisFileIsNotAnExecutable;
867
if (GetDefaultSrcOSForTargetOS(GetCompiledTargetOS)='win') then begin
868
// under Windows the make.exe is in the same directory as fpc.exe
869
if not FileExistsCached(ExtractFilePath(AFilename)+'fpc.exe') then begin
870
Note:='There is no fpc.exe in the directory of the '+ExtractFilename(AFilename)+'. Usually the make executable is installed together with the fpc compiler.';
871
Result:=sddqIncomplete;
875
Result:=sddqCompatible;
878
function SearchMakeExeCandidates(StopIfFits: boolean): TObjectList;
880
function CheckFile(AFilename: string; var List: TObjectList): boolean;
883
RealFilename: String;
886
if AFilename='' then exit;
887
DoDirSeparators(AFilename);
888
// check if already checked
889
if CaptionInSDFileList(AFilename,List) then exit;
890
EnvironmentOptions.MakeFilename:=AFilename;
891
RealFilename:=EnvironmentOptions.GetParsedMakeFilename;
892
debugln(['SearchMakeExeCandidates Value=',AFilename,' File=',RealFilename]);
893
if RealFilename='' then exit;
895
if not FileExistsCached(RealFilename) then exit;
896
// add to list and check quality
897
Item:=TSDFileInfo.Create;
898
Item.Filename:=RealFilename;
899
Item.Quality:=CheckMakeExeQuality(RealFilename,Item.Note);
900
Item.Caption:=AFilename;
902
List:=TObjectList.create(true);
904
Result:=(Item.Quality=sddqCompatible) and StopIfFits;
908
OldMakeFilename: String;
915
OldMakeFilename:=EnvironmentOptions.MakeFilename;
917
// check current setting
918
if CheckFile(EnvironmentOptions.MakeFilename,Result) then exit;
920
// check the primary options
921
AFilename:=GetValueFromPrimaryConfig(EnvOptsConfFileName,
922
'EnvironmentOptions/MakeFilename/Value');
923
if CheckFile(AFilename,Result) then exit;
925
// check the secondary options
926
AFilename:=GetValueFromSecondaryConfig(EnvOptsConfFileName,
927
'EnvironmentOptions/MakeFilename/Value');
928
if CheckFile(AFilename,Result) then exit;
930
if (GetDefaultSrcOSForTargetOS(GetCompiledTargetOS)='win') then begin
931
// check make in fpc.exe directory
932
if CheckFile(SetDirSeparators('$Path($(CompPath))/make.exe'),Result)
937
Files:=EnvironmentOptions.MakeFileHistory;
939
for i:=0 to Files.Count-1 do
940
if CheckFile(Files[i],Result) then exit;
948
AFilename+=GetExecutableExt;
949
if CheckFile(FindDefaultExecutablePath(AFilename),Result) then exit;
951
// check common directories
952
Files:=TStringList.Create;
954
GetDefaultMakeFilenames(Files);
955
for i:=0 to Files.Count-1 do
956
if CheckFile(Files[i],Result) then exit;
961
EnvironmentOptions.MakeFilename:=OldMakeFilename;
965
procedure SetupMakeExe;
969
Quality: TSDFilenameQuality;
970
BestDir: TSDFileInfo;
973
Filename:=EnvironmentOptions.GetParsedMakeFilename;
974
Quality:=CheckMakeExeQuality(Filename,Note);
975
if Quality<>sddqInvalid then exit;
977
dbgout('SetupMakeExe:');
978
if EnvironmentOptions.MakeFilename<>'' then
980
dbgout(' The "make" executable "',EnvironmentOptions.MakeFilename,'"');
981
if EnvironmentOptions.MakeFilename<>Filename then
982
dbgout(' => "',Filename,'"');
983
dbgout(' is invalid (Error: ',Note,')');
984
debugln(' Searching a proper one ...');
986
debugln(' Searching "make" ...');
988
List:=SearchMakeExeCandidates(true);
992
BestDir:=TSDFileInfo(List[List.Count-1]);
993
if (BestDir=nil) or (BestDir.Quality=sddqInvalid) then begin
994
debugln(['SetupMakeExe: no proper "make" found.']);
997
EnvironmentOptions.MakeFilename:=BestDir.Filename;
998
debugln(['SetupMakeExe: using ',EnvironmentOptions.MakeFilename]);
1004
function GetValueFromPrimaryConfig(OptionFilename, Path: string): string;
1006
if not FilenameIsAbsolute(OptionFilename) then
1007
OptionFilename:=AppendPathDelim(GetPrimaryConfigPath)+OptionFilename;
1008
Result:=GetValueFromIDEConfig(OptionFilename,Path);
188
1011
function GetValueFromSecondaryConfig(OptionFilename, Path: string): string;
1013
if not FilenameIsAbsolute(OptionFilename) then
1014
OptionFilename:=AppendPathDelim(GetSecondaryConfigPath)+OptionFilename;
1015
Result:=GetValueFromIDEConfig(OptionFilename,Path);
1018
function GetValueFromIDEConfig(OptionFilename, Path: string): string;
190
1020
XMLConfig: TXMLConfig;
192
if not FilenameIsAbsolute(OptionFilename) then
193
OptionFilename:=AppendPathDelim(GetSecondaryConfigPath)+OptionFilename;
194
1023
if FileExistsCached(OptionFilename) then
204
1033
on E: Exception do begin
205
debugln(['GetValueFromSecondaryConfig File='+OptionFilename+': '+E.Message]);
1034
debugln(['GetValueFromIDEConfig File='+OptionFilename+': '+E.Message]);
1040
function ShowInitialSetupDialog: TModalResult;
1042
InitialSetupDialog: TInitialSetupDialog;
1044
InitialSetupDialog:=TInitialSetupDialog.Create(nil);
1046
Application.TaskBarBehavior:=tbMultiButton;
1047
InitialSetupDialog.Init;
1048
Result:=InitialSetupDialog.ShowModal;
1050
InitialSetupDialog.Free;
1051
Application.TaskBarBehavior:=tbDefault;
1057
procedure TSetupMacros.DoSubstitution(TheMacro: TTransferMacro;
1058
const MacroName: string; var s: string; const Data: PtrInt; var Handled,
1059
Abort: boolean; Depth: integer);
1062
if CompareText(MacroName,'ENV')=0 then
1063
s:=GetEnvironmentVariableUTF8(MacroName)
1064
else if CompareText(MacroName,'PrimaryConfigPath')=0 then
1065
s:=GetPrimaryConfigPath
1066
else if CompareText(MacroName,'SecondaryConfigPath')=0 then
1067
s:=GetSecondaryConfigPath
1068
else if CompareText(MacroName,'FPCVer')=0 then begin
1072
s:={$I %FPCVERSION%};
1073
end else if CompareText(MacroName,'LazarusDir')=0 then begin
1074
if LazarusDir<>'' then
1077
s:='<LazarusDirNotSet>';
1078
end else if (CompareText(MacroName,'TargetOS')=0) then
1079
s:=GetCompiledTargetOS
1080
else if (CompareText(MacroName,'TargetCPU')=0) then
1081
s:=GetCompiledTargetCPU
1082
else if (CompareText(MacroName,'SrcOS')=0) then
1083
s:=GetDefaultSrcOSForTargetOS(GetCompiledTargetOS)
1086
//debugln(['TSetupMacros.DoSubstitution MacroName=',MacroName,' Value="',s,'"']);
1091
{ TInitialSetupDialog }
1093
procedure TInitialSetupDialog.FormCreate(Sender: TObject);
1095
Caption:=Format(lisWelcomeToLazarusIDE, [GetLazarusVersionString]);
1097
StartIDEBitBtn.Caption:=lisStartIDE;
1099
LazarusTabSheet.Caption:='Lazarus';
1100
CompilerTabSheet.Caption:=lisCompiler;
1101
FPCSourcesTabSheet.Caption:=lisFPCSources;
1103
FHeadGraphic:=TPortableNetworkGraphic.Create;
1104
FHeadGraphic.LoadFromLazarusResource('ide_icon48x48');
1106
TVNodeLazarus:=PropertiesTreeView.Items.Add(nil,LazarusTabSheet.Caption);
1107
TVNodeCompiler:=PropertiesTreeView.Items.Add(nil,CompilerTabSheet.Caption);
1108
TVNodeFPCSources:=PropertiesTreeView.Items.Add(nil,FPCSourcesTabSheet.Caption);
1109
ImgIDError := ImageList1.AddLazarusResource('state_error');
1110
ImgIDWarning := ImageList1.AddLazarusResource('state_warning');
1112
LazDirBrowseButton.Caption:=lisPathEditBrowse;
1113
LazDirLabel.Caption:=Format(
1114
lisTheLazarusDirectoryContainsTheSourcesOfTheIDEAndTh, [PathDelim]);
1116
CompilerBrowseButton.Caption:=lisPathEditBrowse;
1117
CompilerLabel.Caption:=Format(
1118
lisTheFreePascalCompilerExecutableTypicallyHasTheName, [DefineTemplates.
1119
GetDefaultCompilerFilename, DefineTemplates.GetDefaultCompilerFilename(
1120
GetCompiledTargetCPU)]);
1122
FPCSrcDirBrowseButton.Caption:=lisPathEditBrowse;
1123
FPCSrcDirLabel.Caption:=Format(
1124
lisTheSourcesOfTheFreePascalPackagesAreRequiredForBro, [SetDirSeparators('rtl'
1125
+'/linux/system.pp')]);
1127
Application.AddOnActivateHandler(@OnAppActivate);
1130
procedure TInitialSetupDialog.CompilerComboBoxChange(Sender: TObject);
1135
procedure TInitialSetupDialog.CompilerBrowseButtonClick(Sender: TObject);
1141
Dlg:=TOpenDialog.Create(nil);
1143
Filename:='fpc'+GetExecutableExt;
1144
Dlg.Title:=Format(lisSelectPathTo, [Filename]);
1145
Dlg.Options:=Dlg.Options+[ofFileMustExist];
1146
Filter:=dlgAllFiles+'|'+GetAllFilesMask;
1147
if ExtractFileExt(Filename)<>'' then
1148
Filter:=lisExecutable+'|*'+ExtractFileExt(Filename)+'|'+Filter;
1150
if not Dlg.Execute then exit;
1151
Filename:=Dlg.FileName;
1155
CompilerComboBox.Text:=Filename;
1159
procedure TInitialSetupDialog.FormDestroy(Sender: TObject);
1163
IdleConnected:=false;
1164
for d:=low(FCandidates) to high(FCandidates) do
1165
FreeAndNil(FCandidates[d]);
1166
FreeAndNil(FHeadGraphic);
1169
procedure TInitialSetupDialog.FPCSrcDirBrowseButtonClick(Sender: TObject);
1173
Dir:=SelectDirectory(lisSelectFPCSourceDirectory);
1174
if Dir='' then exit;
1175
FPCSrcDirComboBox.Text:=Dir;
1176
UpdateFPCSrcDirNote;
1179
procedure TInitialSetupDialog.FPCSrcDirComboBoxChange(Sender: TObject);
1181
UpdateFPCSrcDirNote;
1184
procedure TInitialSetupDialog.LazDirBrowseButtonClick(Sender: TObject);
1188
Dir:=SelectDirectory(lisSelectLazarusSourceDirectory);
1189
if Dir='' then exit;
1190
LazDirComboBox.Text:=Dir;
1194
procedure TInitialSetupDialog.LazDirComboBoxChange(Sender: TObject);
1199
procedure TInitialSetupDialog.OnAppActivate(Sender: TObject);
1201
// switched back from another application
1202
InvalidateFileStateCache;
1205
procedure TInitialSetupDialog.PropertiesPageControlChange(Sender: TObject);
1210
if PropertiesPageControl.ActivePage=nil then exit;
1211
s:=PropertiesPageControl.ActivePage.Caption;
1212
for i:=0 to PropertiesTreeView.Items.TopLvlCount-1 do
1213
if PropertiesTreeView.Items.TopLvlItems[i].Text=s then
1214
PropertiesTreeView.Selected:=PropertiesTreeView.Items.TopLvlItems[i];
1217
procedure TInitialSetupDialog.PropertiesTreeViewSelectionChanged(Sender: TObject);
1219
if PropertiesTreeView.Selected=nil then
1220
SelectPage(TVNodeLazarus.Text)
1222
SelectPage(PropertiesTreeView.Selected.Text);
1225
procedure TInitialSetupDialog.StartIDEBitBtnClick(Sender: TObject);
1229
MsgResult: TModalResult;
1231
Node:=FirstErrorNode;
1232
if Node=TVNodeLazarus then
1233
s:=lisWithoutAProperLazarusDirectoryYouWillGetALotOfWarn
1234
else if Node=TVNodeCompiler then
1235
s:=lisWithoutAProperCompilerTheCodeBrowsingAndCompilingW
1236
else if Node=TVNodeFPCSources then
1237
s:=lisWithoutTheProperFPCSourcesCodeBrowsingAndCompletio;
1239
MsgResult:=MessageDlg(lisCCOWarningCaption, s, mtWarning, [mbIgnore,
1241
if MsgResult<>mrIgnore then exit;
1244
s:=LazDirComboBox.Text;
1246
EnvironmentOptions.LazarusDirectory:=s;
1247
s:=CompilerComboBox.Text;
1249
EnvironmentOptions.CompilerFilename:=s;
1250
s:=FPCSrcDirComboBox.Text;
1252
EnvironmentOptions.FPCSourceDirectory:=s;
1259
procedure TInitialSetupDialog.WelcomePaintBoxPaint(Sender: TObject);
1261
with WelcomePaintBox.Canvas do begin
1262
GradientFill(WelcomePaintBox.ClientRect,$854b32,$c88e60,gdHorizontal);
1263
Draw(0,WelcomePaintBox.ClientHeight-FHeadGraphic.Height,FHeadGraphic);
1264
Font.Color:=clWhite;
1266
Brush.Style:=bsClear;
1267
TextOut(FHeadGraphic.Width+15, 5, lisConfigureLazarusIDE);
1271
procedure TInitialSetupDialog.OnIdle(Sender: TObject; var Done: Boolean);
1273
if FLazarusDirChanged then begin
1274
UpdateCompilerFilenameCandidates;
1276
end else if fCompilerFilenameChanged then begin
1277
UpdateFPCSrcDirCandidates;
1278
UpdateFPCSrcDirNote;
1280
IdleConnected:=false;
1283
procedure TInitialSetupDialog.SelectPage(const NodeText: string);
1288
if FSelectingPage then exit;
1289
FSelectingPage:=true;
1291
for i:=0 to PropertiesTreeView.Items.TopLvlCount-1 do begin
1292
Node:=PropertiesTreeView.Items.TopLvlItems[i];
1293
if Node.Text=NodeText then begin
1294
PropertiesTreeView.Selected:=Node;
1295
PropertiesPageControl.ActivePageIndex:=i;
1300
FSelectingPage:=false;
1304
function TInitialSetupDialog.SelectDirectory(aTitle: string): string;
1306
DirDlg: TSelectDirectoryDialog;
1309
DirDlg:=TSelectDirectoryDialog.Create(nil);
1311
DirDlg.Title:=aTitle;
1312
DirDlg.Options:=DirDlg.Options+[ofPathMustExist,ofFileMustExist];
1313
if not DirDlg.Execute then exit;
1314
Result:=DirDlg.FileName;
1320
procedure TInitialSetupDialog.UpdateLazarusDirCandidates;
1324
Dirs:=SearchLazarusDirectoryCandidates(false);
1325
FreeAndNil(FCandidates[sddtLazarusSrcDir]);
1326
FCandidates[sddtLazarusSrcDir]:=Dirs;
1327
FillComboboxWithFileInfoList(LazDirComboBox,Dirs);
1330
procedure TInitialSetupDialog.UpdateCompilerFilenameCandidates;
1334
FLazarusDirChanged:=false;
1335
Files:=SearchCompilerCandidates(false,
1336
CodeToolBoss.FPCDefinesCache.TestFilename);
1337
FreeAndNil(FCandidates[sddtCompilerFilename]);
1338
FCandidates[sddtCompilerFilename]:=Files;
1339
FillComboboxWithFileInfoList(CompilerComboBox,Files);
1342
procedure TInitialSetupDialog.UpdateFPCSrcDirCandidates;
1346
fCompilerFilenameChanged:=false;
1347
Dirs:=SearchFPCSrcDirCandidates(false,GetFPCVer);
1348
FreeAndNil(FCandidates[sddtFPCSrcDir]);
1349
FCandidates[sddtFPCSrcDir]:=Dirs;
1350
FillComboboxWithFileInfoList(FPCSrcDirComboBox,Dirs);
1353
procedure TInitialSetupDialog.FillComboboxWithFileInfoList(ABox: TComboBox;
1354
List: TObjectList; ItemIndex: integer);
1359
sl:=TStringList.Create;
1362
for i:=0 to List.Count-1 do
1363
sl.Add(TSDFileInfo(List[i]).Caption);
1364
ABox.Items.Assign(sl);
1365
if (ItemIndex>=0) and (ItemIndex<sl.Count) then
1366
ABox.Text:=sl[ItemIndex]
1367
else if ABox.Text=ABox.Name then
1374
procedure TInitialSetupDialog.SetIdleConnected(const AValue: boolean);
1376
if FIdleConnected=AValue then exit;
1377
FIdleConnected:=AValue;
1378
if IdleConnected then
1379
Application.AddOnIdleHandler(@OnIdle)
1381
Application.RemoveOnIdleHandler(@OnIdle);
1384
procedure TInitialSetupDialog.UpdateLazDirNote;
1388
Quality: TSDFilenameQuality;
1390
ImageIndex: Integer;
1392
if csDestroying in ComponentState then exit;
1393
CurCaption:=LazDirComboBox.Text;
1394
CurCaption:=ChompPathDelim(CurCaption);
1395
EnvironmentOptions.LazarusDirectory:=CurCaption;
1396
if FLastParsedLazDir=EnvironmentOptions.GetParsedLazarusDirectory then exit;
1397
FLastParsedLazDir:=EnvironmentOptions.GetParsedLazarusDirectory;
1398
//debugln(['TInitialSetupDialog.UpdateLazDirNote ',FLastParsedLazDir]);
1399
Quality:=CheckLazarusDirectoryQuality(FLastParsedLazDir,Note);
1401
sddqInvalid: s:=lisError;
1402
sddqCompatible: s:='';
1405
if EnvironmentOptions.LazarusDirectory<>EnvironmentOptions.GetParsedLazarusDirectory
1407
s:=lisDirectory+EnvironmentOptions.GetParsedLazarusDirectory+LineEnding+
1409
LazDirMemo.Text:=s+Note;
1411
ImageIndex:=QualityToImgIndex(Quality);
1412
TVNodeLazarus.ImageIndex:=ImageIndex;
1413
TVNodeLazarus.SelectedIndex:=ImageIndex;
1415
FLazarusDirChanged:=true;
1416
IdleConnected:=true;
1419
procedure TInitialSetupDialog.UpdateCompilerNote;
1423
Quality: TSDFilenameQuality;
1425
ImageIndex: Integer;
1427
if csDestroying in ComponentState then exit;
1428
CurCaption:=CompilerComboBox.Text;
1429
EnvironmentOptions.CompilerFilename:=CurCaption;
1430
if fLastParsedCompiler=EnvironmentOptions.GetParsedCompilerFilename then exit;
1431
fLastParsedCompiler:=EnvironmentOptions.GetParsedCompilerFilename;
1432
//debugln(['TInitialSetupDialog.UpdateCompilerNote ',fLastParsedCompiler]);
1433
Quality:=CheckCompilerQuality(fLastParsedCompiler,Note,
1434
CodeToolBoss.FPCDefinesCache.TestFilename);
1435
if Quality<>sddqInvalid then begin
1436
CodeToolBoss.FPCDefinesCache.ConfigCaches.Find(
1437
fLastParsedCompiler,'','','',true);
1441
sddqInvalid: s:=lisError;
1442
sddqCompatible: s:='';
1445
if EnvironmentOptions.CompilerFilename<>EnvironmentOptions.GetParsedCompilerFilename
1447
s:=lisFile2+EnvironmentOptions.GetParsedCompilerFilename+LineEnding+
1449
CompilerMemo.Text:=s+Note;
1451
ImageIndex:=QualityToImgIndex(Quality);
1452
TVNodeCompiler.ImageIndex:=ImageIndex;
1453
TVNodeCompiler.SelectedIndex:=ImageIndex;
1455
fCompilerFilenameChanged:=true;
1456
IdleConnected:=true;
1459
procedure TInitialSetupDialog.UpdateFPCSrcDirNote;
1463
Quality: TSDFilenameQuality;
1465
ImageIndex: Integer;
1467
if csDestroying in ComponentState then exit;
1468
CurCaption:=FPCSrcDirComboBox.Text;
1469
CurCaption:=ChompPathDelim(CurCaption);
1470
EnvironmentOptions.FPCSourceDirectory:=CurCaption;
1471
if fLastParsedFPCSrcDir=EnvironmentOptions.GetParsedFPCSourceDirectory then exit;
1472
fLastParsedFPCSrcDir:=EnvironmentOptions.GetParsedFPCSourceDirectory;
1473
//debugln(['TInitialSetupDialog.UpdateFPCSrcDirNote ',fLastParsedFPCSrcDir]);
1474
Quality:=CheckFPCSrcDirQuality(fLastParsedFPCSrcDir,Note,GetFPCVer);
1476
sddqInvalid: s:=lisError;
1477
sddqCompatible: s:='';
1480
if EnvironmentOptions.FPCSourceDirectory<>EnvironmentOptions.GetParsedFPCSourceDirectory
1482
s:=lisDirectory+EnvironmentOptions.GetParsedFPCSourceDirectory+LineEnding+
1484
FPCSrcDirMemo.Text:=s+Note;
1486
ImageIndex:=QualityToImgIndex(Quality);
1487
TVNodeFPCSources.ImageIndex:=ImageIndex;
1488
TVNodeFPCSources.SelectedIndex:=ImageIndex;
1491
function TInitialSetupDialog.FirstErrorNode: TTreeNode;
1495
for i:=0 to PropertiesTreeView.Items.TopLvlCount-1 do
1497
Result:=PropertiesTreeView.Items.TopLvlItems[i];
1498
if Result.ImageIndex=ImgIDError then exit;
1503
function TInitialSetupDialog.GetFPCVer: string;
1505
Result:='$(FPCVer)';
1506
GlobalMacroList.SubstituteStr(Result);
1509
function TInitialSetupDialog.GetFirstCandidate(Candidates: TObjectList;
1510
MinQuality: TSDFilenameQuality): TSDFileInfo;
1514
if Candidates<>nil then
1515
for i:=0 to Candidates.Count-1 do begin
1516
Result:=TSDFileInfo(Candidates[i]);
1517
if Result.Quality>=MinQuality then
1523
function TInitialSetupDialog.QualityToImgIndex(Quality: TSDFilenameQuality
1526
if Quality=sddqCompatible then
1528
else if Quality=sddqWrongMinorVersion then
1529
Result:=ImgIDWarning
1534
procedure TInitialSetupDialog.Init;
1537
Candidate: TSDFileInfo;
1538
IsFirstStart: Boolean;
1539
PrimaryFilename: String;
1540
SecondaryFilename: String;
1541
PrimaryEnvs: TStringListUTF8;
1542
SecondaryEnvs: TStringListUTF8;
1544
IsFirstStart:=not FileExistsCached(EnvironmentOptions.Filename);
1545
if not IsFirstStart then begin
1546
PrimaryFilename:=EnvironmentOptions.Filename;
1547
SecondaryFilename:=AppendPathDelim(GetSecondaryConfigPath)+ExtractFilename(PrimaryFilename);
1548
if FileExistsUTF8(PrimaryFilename)
1549
and FileExistsUTF8(SecondaryFilename) then begin
1550
// compare content of primary and secondary config
1551
PrimaryEnvs:=TStringListUTF8.Create;
1552
SecondaryEnvs:=TStringListUTF8.Create;
1554
PrimaryEnvs.LoadFromFile(PrimaryFilename);
1557
debugln(['TInitialSetupDialog.Init unable to read "'+PrimaryFilename+'": '+E.Message]);
1560
SecondaryEnvs.LoadFromFile(SecondaryFilename);
1563
debugln(['TInitialSetupDialog.Init unable to read "'+SecondaryFilename+'": '+E.Message]);
1565
IsFirstStart:=PrimaryEnvs.Text=SecondaryEnvs.Text;
1570
//debugln(['TInitialSetupDialog.Init IsFirstStart=',IsFirstStart,' ',EnvironmentOptions.Filename]);
1572
// Lazarus directory
1573
UpdateLazarusDirCandidates;
1574
if IsFirstStart or (not FileExistsCached(EnvironmentOptions.GetParsedLazarusDirectory))
1576
// first start => choose first best candidate
1577
Candidate:=GetFirstCandidate(FCandidates[sddtLazarusSrcDir]);
1578
if Candidate<>nil then
1579
EnvironmentOptions.LazarusDirectory:=Candidate.Caption;
1581
LazDirComboBox.Text:=EnvironmentOptions.LazarusDirectory;
1582
FLastParsedLazDir:='. .';
1584
FLazarusDirChanged:=false;
1586
// compiler filename
1587
UpdateCompilerFilenameCandidates;
1588
if IsFirstStart or (not FileExistsCached(EnvironmentOptions.GetParsedCompilerFilename))
1590
// first start => choose first best candidate
1591
Candidate:=GetFirstCandidate(FCandidates[sddtCompilerFilename]);
1592
if Candidate<>nil then
1593
EnvironmentOptions.CompilerFilename:=Candidate.Caption;
1595
CompilerComboBox.Text:=EnvironmentOptions.CompilerFilename;
1596
fLastParsedCompiler:='. .';
1598
fCompilerFilenameChanged:=false;
1600
// FPC source directory
1601
UpdateFPCSrcDirCandidates;
1602
if IsFirstStart or (not FileExistsCached(EnvironmentOptions.GetParsedFPCSourceDirectory))
1604
// first start => choose first best candidate
1605
Candidate:=GetFirstCandidate(FCandidates[sddtFPCSrcDir]);
1606
if Candidate<>nil then
1607
EnvironmentOptions.FPCSourceDirectory:=Candidate.Caption;
1609
FPCSrcDirComboBox.Text:=EnvironmentOptions.FPCSourceDirectory;
1610
fLastParsedFPCSrcDir:='. .';
1611
UpdateFPCSrcDirNote;
1613
// select first error
1614
Node:=FirstErrorNode;
1616
Node:=TVNodeLazarus;
1617
PropertiesTreeView.Selected:=Node;