mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-05 15:37:50 +02:00
1702 lines
53 KiB
ObjectPascal
1702 lines
53 KiB
ObjectPascal
{
|
|
/***************************************************************************
|
|
initialsetupdlgs.pas
|
|
--------------------
|
|
Contains the dialogs to help users setup basic settings.
|
|
|
|
|
|
***************************************************************************/
|
|
|
|
***************************************************************************
|
|
* *
|
|
* This source is free software; you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
* (at your option) any later version. *
|
|
* *
|
|
* This code is distributed in the hope that it will be useful, but *
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
|
* General Public License for more details. *
|
|
* *
|
|
* A copy of the GNU General Public License is available on the World *
|
|
* Wide Web at <http://www.gnu.org/copyleft/gpl.html>. You can also *
|
|
* obtain it by writing to the Free Software Foundation, *
|
|
* Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1335, USA. *
|
|
* *
|
|
***************************************************************************
|
|
|
|
Author: Mattias Gaertner
|
|
|
|
Abstract:
|
|
Contains the dialogs to help users setup basic settings.
|
|
}
|
|
unit InitialSetupDlgs;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
{off $DEFINE VerboseFPCSrcScanThead}
|
|
|
|
interface
|
|
|
|
uses
|
|
// RTL + FCL
|
|
Classes, SysUtils, fgl, pkgglobals, fpmkunit,
|
|
// LCL
|
|
Forms, Controls, Buttons, Dialogs, Graphics, ComCtrls, ExtCtrls, StdCtrls,
|
|
// CodeTools
|
|
FileProcs, CodeToolManager, DefineTemplates,
|
|
// LazUtils
|
|
FPCAdds, FileUtil, LazUTF8, LazFileUtils, LazFileCache, LazLoggerBase,
|
|
// IdeIntf
|
|
IdeIntfStrConsts, MacroDefIntf, IDEDialogs, IDEImagesIntf, IDEUtils,
|
|
// DebuggerIntf
|
|
DbgIntfDebuggerBase,
|
|
// LazDebuggerGdbmi
|
|
GDBMIDebugger, DividerBevel,
|
|
// IdeConfig
|
|
LazConf, EnvironmentOpts, TransferMacros, IDEProcs,
|
|
// IDE
|
|
LazarusIDEStrConsts, IDETranslations, BaseBuildManager, InitialSetupProc,
|
|
GenerateFppkgConfigurationDlg, LazarusPackageIntf, InitialSetupDlgDebuggerFrame, IdeDebuggerOpts;
|
|
|
|
type
|
|
TInitialSetupDialog = class;
|
|
|
|
TSetupFrameInfo = record
|
|
Node: TTreeNode;
|
|
Page: TTabSheet;
|
|
State: TInitSetupDlgFrameState;
|
|
Action: TInitSetupDlgFrameAction;
|
|
Group: String;
|
|
end;
|
|
TSetupDlgFrameMap = specialize TFPGMap<Pointer{ISetupDlgFrame}, TSetupFrameInfo>;
|
|
TGroupMap = specialize TFPGMap<string, TSetupFrameInfo>;
|
|
|
|
{ TSearchFpcSourceThread }
|
|
|
|
TSearchFpcSourceThread = class(TThread)
|
|
private
|
|
fSetupDialog: TInitialSetupDialog;
|
|
fFPCVer: string;
|
|
fFoundFPCSrc: TSDFileInfo;
|
|
{$IFDEF VerboseFPCSrcScanThead}
|
|
fPath: string;
|
|
fFileInfo: TSearchRec;
|
|
procedure Debug;
|
|
{$ENDIF}
|
|
function CheckFPCSrcDir(Dir: string): TSDFileInfo;
|
|
procedure DoSearch(const APath: String);
|
|
procedure UpdateFPCSrcDir;
|
|
procedure Finishing;
|
|
protected
|
|
procedure Execute; override;
|
|
public
|
|
constructor Create(aSetupDialog: TInitialSetupDialog);
|
|
destructor Destroy; override;
|
|
end;
|
|
|
|
{ TInitialSetupDialog }
|
|
|
|
TInitialSetupDialog = class(TForm, ISetupDlgProvider)
|
|
BtnPanel: TPanel;
|
|
CompilerBrowseButton: TButton;
|
|
CompilerComboBox: TComboBox;
|
|
CompilerLabel: TLabel;
|
|
CompilerMemo: TMemo;
|
|
CompilerTabSheet: TTabSheet;
|
|
DebuggerTabSheet: TTabSheet;
|
|
FPCSourcesTabSheet: TTabSheet;
|
|
FPCSrcDirBrowseButton: TButton;
|
|
FPCSrcDirComboBox: TComboBox;
|
|
FPCSrcDirLabel: TLabel;
|
|
FPCSrcDirMemo: TMemo;
|
|
ImageList1: TImageList;
|
|
LazarusTabSheet: TTabSheet;
|
|
LazDirBrowseButton: TButton;
|
|
LazDirComboBox: TComboBox;
|
|
LazDirLabel: TLabel;
|
|
LazDirMemo: TMemo;
|
|
MakeExeBrowseButton: TButton;
|
|
MakeExeComboBox: TComboBox;
|
|
MakeExeLabel: TLabel;
|
|
MakeExeMemo: TMemo;
|
|
MakeExeTabSheet: TTabSheet;
|
|
PropertiesPageControl: TPageControl;
|
|
PropertiesTreeView: TTreeView;
|
|
ScanLabel: TLabel;
|
|
ScanProgressBar: TProgressBar;
|
|
Splitter1: TSplitter;
|
|
StartIDEBitBtn: TBitBtn;
|
|
StopScanButton: TBitBtn;
|
|
WelcomePaintBox: TPaintBox;
|
|
FppkgTabSheet: TTabSheet;
|
|
FppkgComboBox: TComboBox;
|
|
FppkgLabel: TLabel;
|
|
FppkgBrowseButton: TButton;
|
|
FppkgMemo: TMemo;
|
|
FppkgWriteConfigButton: TButton;
|
|
procedure CompilerBrowseButtonClick(Sender: TObject);
|
|
procedure CompilerComboBoxChange(Sender: TObject);
|
|
procedure CompilerComboBoxExit(Sender: TObject);
|
|
procedure FormCreate(Sender: TObject);
|
|
procedure FormDestroy(Sender: TObject);
|
|
procedure FPCSrcDirBrowseButtonClick(Sender: TObject);
|
|
procedure FPCSrcDirComboBoxChange(Sender: TObject);
|
|
procedure LazDirBrowseButtonClick(Sender: TObject);
|
|
procedure LazDirComboBoxChange(Sender: TObject);
|
|
procedure MakeExeBrowseButtonClick(Sender: TObject);
|
|
procedure MakeExeComboBoxChange(Sender: TObject);
|
|
procedure OnAppActivate(Sender: TObject);
|
|
procedure PropertiesPageControlChange(Sender: TObject);
|
|
procedure PropertiesTreeViewSelectionChanged(Sender: TObject);
|
|
procedure StartIDEBitBtnClick(Sender: TObject);
|
|
procedure StopScanButtonClick(Sender: TObject);
|
|
procedure WelcomePaintBoxPaint(Sender: TObject);
|
|
procedure OnIdle(Sender: TObject; var {%H-}Done: Boolean);
|
|
procedure FppkgComboBoxChange(Sender: TObject);
|
|
procedure FppkgBrowseButtonClick(Sender: TObject);
|
|
procedure FppkgWriteConfigButtonClick(Sender: TObject);
|
|
private
|
|
FInitDebuggerFrame: TInitDebuggerFrame;
|
|
FSetupDlgFrameMap: TSetupDlgFrameMap;
|
|
FSetupDlgGroupMap: TGroupMap;
|
|
FFlags: TSDFlags;
|
|
FLastParsedLazDir: string;
|
|
fLastParsedCompiler: string;
|
|
fLastParsedFPCSrcDir: string;
|
|
fLastParsedMakeExe: string;
|
|
fLastParsedFppkgConfigFile: string;
|
|
FIdleConnected: boolean;
|
|
ImgIDFatal: LongInt;
|
|
ImgIDError: LongInt;
|
|
ImgIDWarning: LongInt;
|
|
ImgIDNote: LongInt;
|
|
ImgIDHint: LongInt;
|
|
ImgIDInfo: LongInt;
|
|
FHeadGraphic: TPortableNetworkGraphic;
|
|
FSelectingPage: boolean;
|
|
FCandidates: array[TSDFilenameType] of TSDFileInfoList; // list of TSDFileInfo
|
|
fSearchFpcSourceThread: TSearchFpcSourceThread;
|
|
procedure DoDbgFrameStateChanged(AState: TSDFilenameQuality);
|
|
procedure FrameStateChanged(AnSender: ISetupDlgFrame; AState: TInitSetupDlgFrameState; AnAction: TInitSetupDlgFrameAction);
|
|
procedure SetGroupCaption(AGroupId, AName: String);
|
|
procedure UpdateCaptions;
|
|
procedure SelectPage(const ATreeNode: TTreeNode; AnUserSelect: Boolean = False);
|
|
function SelectDirectory(aTitle: string): string;
|
|
function SelectDirectory(aTitle: string; aPathFileName: string;
|
|
aEnvOptParseType: TEnvOptParseType): string; overload;
|
|
procedure StartFPCSrcThread;
|
|
procedure UpdateLazarusDirCandidates;
|
|
procedure UpdateCompilerFilenameCandidates;
|
|
procedure UpdateFPCSrcDirCandidates;
|
|
procedure UpdateFPCSrcDirCandidate(aFPCSrcDirInfo: TSDFileInfo);
|
|
procedure UpdateMakeExeCandidates(aStopIfFits: boolean = False);
|
|
procedure UpdateFppkgCandidates;
|
|
procedure FillComboboxWithFileInfoList(ABox: TComboBox; List: TSDFileInfoList;
|
|
ItemIndex: integer = 0);
|
|
procedure SetIdleConnected(const AValue: boolean);
|
|
procedure UpdateLazDirNote;
|
|
procedure UpdateCompilerNote(aQuiet: boolean = False);
|
|
procedure UpdateFPCSrcDirNote;
|
|
procedure UpdateMakeExeNote;
|
|
procedure UpdateFppkgNote;
|
|
function FirstErrorNode: TTreeNode;
|
|
function FirstWarningNode: TTreeNode;
|
|
function GetFirstCandidate(Candidates: TSDFileInfoList;
|
|
MinQuality: TSDFilenameQuality = sddqCompatible): TSDFileInfo;
|
|
function QualityToImgIndex(Quality: TSDFilenameQuality): integer;
|
|
procedure ShowHideScanControls(aShow: Boolean);
|
|
procedure ThreadTerminated(Sender: TObject); // called in main thread by fSearchFpcSourceThread.OnTerminate
|
|
procedure TranslateResourceStrings;
|
|
public
|
|
TVNodeLazarus: TTreeNode;
|
|
TVNodeCompiler: TTreeNode;
|
|
TVNodeFPCSources: TTreeNode;
|
|
TVNodeMakeExe: TTreeNode;
|
|
TVNodeDebugger: TTreeNode;
|
|
TVNodeFppkg: TTreeNode;
|
|
constructor Create(TheOwner: TComponent); override;
|
|
destructor Destroy; override;
|
|
procedure Init; //Check for config errors, find and show alternatives
|
|
property IdleConnected: boolean read FIdleConnected write SetIdleConnected;
|
|
end;
|
|
|
|
|
|
function ShowInitialSetupDialog: TModalResult;
|
|
|
|
// Debugger
|
|
// Search debugger candidates and add them to list, including quality level
|
|
|
|
implementation
|
|
|
|
type
|
|
|
|
{ TSetupMacros }
|
|
|
|
TSetupMacros = class(TTransferMacroList)
|
|
protected
|
|
procedure DoSubstitution({%H-}TheMacro: TTransferMacro; const MacroName: string;
|
|
var s: string; const {%H-}Data: PtrInt; var Handled, {%H-}Abort: boolean;
|
|
{%H-}Depth: integer); override;
|
|
public
|
|
FPCVer: string;
|
|
LazarusDir: string;
|
|
end;
|
|
|
|
function ShowInitialSetupDialog: TModalResult;
|
|
var
|
|
InitialSetupDialog: TInitialSetupDialog;
|
|
begin
|
|
InitialSetupDialog:=TInitialSetupDialog.Create(nil);
|
|
try
|
|
Application.TaskBarBehavior:=tbMultiButton;
|
|
InitialSetupDialog.Init;
|
|
Result:=InitialSetupDialog.ShowModal;
|
|
finally
|
|
InitialSetupDialog.Free;
|
|
Application.TaskBarBehavior:=tbDefault;
|
|
end;
|
|
end;
|
|
|
|
{ TSearchFpcSourceThread }
|
|
|
|
function DoCompFrameList(const Item1, Item2: ISetupDlgFrame): Integer;
|
|
begin
|
|
Result := Item1.SortOrder - Item2.SortOrder;
|
|
if Result = 0 then begin
|
|
if Item1.UniqueId < Item2.UniqueId then Result := -1;
|
|
if Item1.UniqueId > Item2.UniqueId then Result := 1;
|
|
end;
|
|
end;
|
|
|
|
constructor TSearchFpcSourceThread.Create(aSetupDialog: TInitialSetupDialog);
|
|
begin
|
|
inherited Create(True);
|
|
FreeOnTerminate:=True;
|
|
fSetupDialog:=aSetupDialog;
|
|
end;
|
|
|
|
destructor TSearchFpcSourceThread.Destroy;
|
|
begin
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TSearchFpcSourceThread.Execute;
|
|
var
|
|
RootDir: String;
|
|
begin
|
|
// ToDo: RootDir must be changed for Windows and maybe other systems.
|
|
// GetUserDir returns the user profile dir on Windows.
|
|
RootDir:=GetUserDir;
|
|
// Scan directories under root directory.
|
|
DoSearch(AppendPathDelim(RootDir));
|
|
if Assigned(fFoundFPCSrc) then
|
|
Synchronize(@UpdateFPCSrcDir); // Update GUI in main thread.
|
|
Synchronize(@Finishing);
|
|
end;
|
|
|
|
function TSearchFpcSourceThread.CheckFPCSrcDir(Dir: string): TSDFileInfo;
|
|
var
|
|
RealDir: String;
|
|
begin
|
|
Result:=Nil;
|
|
RealDir:=TrimFilename(Dir);
|
|
if RealDir='' then exit;
|
|
if not DirPathExistsCached(RealDir) then exit; // check if exists
|
|
Result:=TSDFileInfo.Create;
|
|
Result.Filename:=RealDir;
|
|
Result.Caption:=Dir; // check quality
|
|
Result.Quality:=CheckFPCSrcDirQuality(RealDir, Result.Note, fFPCVer, False);
|
|
if Result.Quality<>sddqCompatible then // return only exact matches
|
|
FreeAndNil(Result);
|
|
end;
|
|
|
|
procedure TSearchFpcSourceThread.DoSearch(const APath: String);
|
|
var
|
|
PathInfo: TSearchRec;
|
|
FPCSrc: TSDFileInfo;
|
|
begin
|
|
if FindFirstUTF8(APath+AllDirectoryEntriesMask, faDirectory, PathInfo) = 0 then
|
|
try
|
|
repeat
|
|
if Terminated then Break;
|
|
if (PathInfo.Name='') or (PathInfo.Name[1]='.')
|
|
or ((PathInfo.Attr and faDirectory) = 0) then Continue;
|
|
case lowercase(PathInfo.Name) of
|
|
'pictures',
|
|
'music',
|
|
'photos',
|
|
'movies',
|
|
'videos',
|
|
'calendar',
|
|
'calendars',
|
|
'mail',
|
|
'messages',
|
|
'contacts',
|
|
'cache',
|
|
'caches',
|
|
'trash',
|
|
'containers',
|
|
{$IFDEF darwin}
|
|
'applications',
|
|
{$ENDIF}
|
|
{$IFDEF Linux}
|
|
'proc',
|
|
'sys',
|
|
'dev',
|
|
{$ENDIF}
|
|
'tmp': continue;
|
|
end;
|
|
{$IFDEF VerboseFPCSrcScanThead}
|
|
fPath := APath;
|
|
fFileInfo := PathInfo;
|
|
Synchronize(@Debug);
|
|
{$ENDIF}
|
|
DoSearch(AppendPathDelim(APath+PathInfo.Name)); // Recursive call
|
|
FPCSrc:=CheckFPCSrcDir(APath+PathInfo.Name);
|
|
if Assigned(FPCSrc) then begin
|
|
fFoundFPCSrc:=FPCSrc; // An exact match was found.
|
|
Terminate;
|
|
end;
|
|
until (FindNextUTF8(PathInfo) <> 0);
|
|
finally
|
|
FindCloseUTF8(PathInfo);
|
|
end;
|
|
end;
|
|
|
|
{$IFDEF VerboseFPCSrcScanThead}
|
|
procedure TSearchFpcSourceThread.Debug;
|
|
begin
|
|
DebugLn(['* TSearchFpcSourceThread.Debug: Path=', fPath, ', Name=', fFileInfo.Name]);
|
|
end;
|
|
{$ENDIF}
|
|
|
|
procedure TSearchFpcSourceThread.UpdateFPCSrcDir;
|
|
begin
|
|
DebugLn(['TSearchFpcSourceThread.UpdateFPCSrcDir']);
|
|
fSetupDialog.UpdateFPCSrcDirCandidate(fFoundFPCSrc);
|
|
fSetupDialog.UpdateFPCSrcDirNote;
|
|
end;
|
|
|
|
procedure TSearchFpcSourceThread.Finishing;
|
|
begin
|
|
DebugLn(['TSearchFpcSourceThread.Finishing']);
|
|
fSetupDialog.ShowHideScanControls(False); // Hide scan controls
|
|
end;
|
|
|
|
{ TSetupMacros }
|
|
|
|
procedure TSetupMacros.DoSubstitution(TheMacro: TTransferMacro;
|
|
const MacroName: string; var s: string; const Data: PtrInt; var Handled,
|
|
Abort: boolean; Depth: integer);
|
|
begin
|
|
Handled:=true;
|
|
if CompareText(MacroName,'ENV')=0 then
|
|
s:=GetEnvironmentVariableUTF8(MacroName)
|
|
else if CompareText(MacroName,'PrimaryConfigPath')=0 then
|
|
s:=GetPrimaryConfigPath
|
|
else if CompareText(MacroName,'SecondaryConfigPath')=0 then
|
|
s:=GetSecondaryConfigPath
|
|
else if CompareText(MacroName,'FPCVer')=0 then begin
|
|
if FPCVer<>'' then
|
|
s:=FPCVer
|
|
else
|
|
s:={$I %FPCVERSION%};
|
|
end else if CompareText(MacroName,'LazarusDir')=0 then begin
|
|
if LazarusDir<>'' then
|
|
s:=LazarusDir
|
|
else
|
|
s:='<LazarusDirNotSet>';
|
|
end else if (CompareText(MacroName,'TargetOS')=0) then
|
|
s:=GetCompiledTargetOS
|
|
else if (CompareText(MacroName,'TargetCPU')=0) then
|
|
s:=GetCompiledTargetCPU
|
|
else if (CompareText(MacroName,'SrcOS')=0) then
|
|
s:=GetDefaultSrcOSForTargetOS(GetCompiledTargetOS)
|
|
else
|
|
Handled:=false;
|
|
//debugln(['TSetupMacros.DoSubstitution MacroName=',MacroName,' Value="',s,'"']);
|
|
end;
|
|
|
|
{$R *.lfm}
|
|
|
|
{ TInitialSetupDialog }
|
|
|
|
procedure TInitialSetupDialog.FormCreate(Sender: TObject);
|
|
var
|
|
FrameList: TSetupDlgFrameList;
|
|
i, GrpIdx: Integer;
|
|
NewNode: TTreeNode;
|
|
NewTab: TTabSheet;
|
|
ScrollBox: TScrollBox;
|
|
NewParent: TWinControl;
|
|
CurFrame: ISetupDlgFrame;
|
|
Info, GrpInfo: TSetupFrameInfo;
|
|
Grp: String;
|
|
NewDiv: TDividerBevel;
|
|
begin
|
|
LazarusTabSheet.Caption:='Lazarus';
|
|
CompilerTabSheet.Caption:=lisCompiler;
|
|
FPCSourcesTabSheet.Caption:=lisFPCSources;
|
|
MakeExeTabSheet.Caption:='Make';
|
|
DebuggerTabSheet.Caption:=lisDebugger;
|
|
FppkgTabSheet.Caption := 'Fppkg';
|
|
|
|
FHeadGraphic:=TPortableNetworkGraphic.Create;
|
|
FHeadGraphic.LoadFromResourceName(HInstance, 'ide_icon48x48');
|
|
|
|
TVNodeLazarus:=PropertiesTreeView.Items.Add(nil,LazarusTabSheet.Caption);
|
|
TVNodeCompiler:=PropertiesTreeView.Items.Add(nil,CompilerTabSheet.Caption);
|
|
TVNodeFPCSources:=PropertiesTreeView.Items.Add(nil,FPCSourcesTabSheet.Caption);
|
|
TVNodeMakeExe:=PropertiesTreeView.Items.Add(nil,MakeExeTabSheet.Caption);
|
|
TVNodeDebugger:=PropertiesTreeView.Items.Add(nil,DebuggerTabSheet.Caption);
|
|
|
|
LazarusTabSheet.Tag := PtrUInt(Pointer(TVNodeLazarus));
|
|
CompilerTabSheet.Tag := PtrUInt(Pointer(TVNodeCompiler));
|
|
FPCSourcesTabSheet.Tag := PtrUInt(Pointer(TVNodeFPCSources));
|
|
MakeExeTabSheet.Tag := PtrUInt(Pointer(TVNodeMakeExe));
|
|
DebuggerTabSheet.Tag := PtrUInt(Pointer(TVNodeDebugger));
|
|
|
|
|
|
FppkgTabSheet.TabVisible := EnvironmentOptions.FppkgCheck;
|
|
if FppkgTabSheet.TabVisible then begin
|
|
TVNodeFppkg:=PropertiesTreeView.Items.Add(nil,FppkgTabSheet.Caption);
|
|
FppkgTabSheet.Tag := PtrUInt(Pointer(TVNodeFppkg));
|
|
end;
|
|
ImgIDFatal := Imagelist1.AddResourceName(HInstance, 'state_fatal');
|
|
ImgIDError := Imagelist1.AddResourceName(HInstance, 'state_error');
|
|
ImgIDWarning := Imagelist1.AddResourceName(HInstance, 'state_warning');
|
|
ImgIDNote := Imagelist1.AddResourceName(HInstance, 'state_note');
|
|
ImgIDHint := Imagelist1.AddResourceName(HInstance, 'state_hint');
|
|
ImgIDInfo := Imagelist1.AddResourceName(HInstance, 'state_information');
|
|
|
|
IDEImages.AssignImage(StopScanButton, 'menu_stop');
|
|
|
|
FrameList := SetupDlgFrameList;
|
|
FrameList.Sort(@DoCompFrameList);
|
|
DisableAutoSizing;
|
|
try
|
|
for i := 0 to FrameList.Count - 1 do begin
|
|
CurFrame := FrameList[i];
|
|
Grp := CurFrame.GroupId;
|
|
GrpIdx := -1;
|
|
NewNode := nil;
|
|
if Grp <> '' then begin
|
|
GrpIdx := FSetupDlgGroupMap.IndexOf(Grp);
|
|
if GrpIdx >= 0 then begin
|
|
GrpInfo := FSetupDlgGroupMap.Data[GrpIdx];
|
|
NewNode := GrpInfo.Node;
|
|
NewTab := GrpInfo.Page;
|
|
ScrollBox := NewTab.Controls[0] as TScrollBox;
|
|
end;
|
|
end;
|
|
|
|
if NewNode = nil then begin
|
|
NewNode := PropertiesTreeView.Items.Add(nil, CurFrame.Caption);
|
|
|
|
NewTab := PropertiesPageControl.AddTabSheet;
|
|
NewTab.Caption := CurFrame.Caption;
|
|
NewTab.Tag := PtrUInt(NewNode);
|
|
|
|
ScrollBox := TScrollBox.Create(Self);
|
|
ScrollBox.Parent := NewTab;
|
|
ScrollBox.Align := alClient;
|
|
ScrollBox.HorzScrollBar.Visible := False;
|
|
NewParent := ScrollBox;
|
|
|
|
if (GrpIdx < 0) and (Grp <> '') then begin
|
|
GrpInfo.Node := NewNode;
|
|
GrpInfo.Page := NewTab;
|
|
GrpInfo.State := issOk;
|
|
GrpInfo.Action := isaReady;
|
|
GrpIdx := FSetupDlgGroupMap.Add(Grp, GrpInfo);
|
|
end;
|
|
end;
|
|
if GrpIdx >= 0 then begin
|
|
NewDiv := TDividerBevel.Create(Self);
|
|
NewDiv.Parent := ScrollBox;
|
|
if ScrollBox.ControlCount > 1 then begin
|
|
NewDiv.AnchorSide[akTop].Side := asrBottom;
|
|
NewDiv.AnchorSide[akTop].Control := ScrollBox.Controls[ScrollBox.ControlCount - 2];
|
|
NewDiv.BorderSpacing.Top := 10;
|
|
end
|
|
else begin
|
|
NewDiv.AnchorSide[akTop].Side := asrTop;
|
|
NewDiv.AnchorSide[akTop].Control := ScrollBox;
|
|
end;
|
|
NewDiv.AnchorSide[akLeft].Side := asrTop;
|
|
NewDiv.AnchorSide[akLeft].Control := ScrollBox;
|
|
NewDiv.AnchorSide[akRight].Side := asrBottom;
|
|
NewDiv.AnchorSide[akRight].Control := ScrollBox;
|
|
NewDiv.Anchors := [akTop, akLeft, akRight];
|
|
|
|
NewDiv.Caption := CurFrame.Caption;
|
|
NewParent := TPanel.Create(Self);
|
|
|
|
TPanel(NewParent).Parent := ScrollBox;
|
|
TPanel(NewParent).AnchorSide[akTop].Side := asrBottom;
|
|
TPanel(NewParent).AnchorSide[akTop].Control := NewDiv;
|
|
TPanel(NewParent).AnchorSide[akLeft].Side := asrTop;
|
|
TPanel(NewParent).AnchorSide[akLeft].Control := ScrollBox;
|
|
TPanel(NewParent).AnchorSide[akRight].Side := asrBottom;
|
|
TPanel(NewParent).AnchorSide[akRight].Control := ScrollBox;
|
|
TPanel(NewParent).Anchors := [akTop, akLeft, akRight];
|
|
TPanel(NewParent).AutoSize := True;
|
|
TPanel(NewParent).BevelInner := bvNone;
|
|
TPanel(NewParent).BevelOuter := bvNone;
|
|
end;
|
|
|
|
Info.Node := NewNode;
|
|
Info.Page := NewTab;
|
|
Info.State := issOk;
|
|
Info.Action := isaReady;
|
|
Info.Group := Grp;
|
|
FSetupDlgFrameMap.Add(Pointer(CurFrame), Info);
|
|
|
|
CurFrame.AddToDialog(Self, NewParent, Self);
|
|
end;
|
|
finally
|
|
EnableAutoSizing;
|
|
end;
|
|
|
|
UpdateCaptions;
|
|
|
|
Application.AddOnActivateHandler(@OnAppActivate);
|
|
end;
|
|
|
|
procedure TInitialSetupDialog.CompilerComboBoxChange(Sender: TObject);
|
|
begin
|
|
UpdateCompilerNote({Quiet} True);
|
|
UpdateFPCSrcDirNote;
|
|
end;
|
|
|
|
procedure TInitialSetupDialog.CompilerComboBoxExit(Sender: TObject);
|
|
begin
|
|
UpdateCompilerNote({Quiet} False);
|
|
UpdateFPCSrcDirNote;
|
|
end;
|
|
|
|
procedure TInitialSetupDialog.CompilerBrowseButtonClick(Sender: TObject);
|
|
var
|
|
lExpandedName: string; // Expanded name before Dialog
|
|
lDirName, lFileName: string;
|
|
lTitle: string;
|
|
lChanged: boolean=False;
|
|
Dlg: TIDEOpenDialog;
|
|
Filter: String;
|
|
begin
|
|
Dlg := IDEOpenDialogClass.Create(nil);
|
|
try
|
|
lTitle := 'fpc'+GetExecutableExt;
|
|
Dlg.Title := SimpleFormat(lisSelectPathTo, [lTitle]);
|
|
lExpandedName := EnvironmentOptions.GetParsedValue(eopCompilerFilename, CompilerComboBox.Text);
|
|
lDirName := GetValidDirectory(lExpandedName, {out} lFileName);
|
|
Dlg.Options := Dlg.Options+[ofFileMustExist];
|
|
if lFileName='' then
|
|
lFileName := lTitle;
|
|
Filter := dlgFilterAll+'|'+GetAllFilesMask;
|
|
if ExtractFileExt(lFileName)<>'' then
|
|
Filter := dlgFilterExecutable+'|*'+ExtractFileExt(lFileName)+'|'+Filter;
|
|
Dlg.Filter := Filter;
|
|
Dlg.InitialDir := lDirName;
|
|
Dlg.FileName := lFileName;
|
|
if not Dlg.Execute then
|
|
exit;
|
|
lFileName := CleanAndExpandFilename(Dlg.Filename);
|
|
lChanged := UpperCase(lExpandedName)<>UpperCase(lFileName);
|
|
finally
|
|
Dlg.Free;
|
|
end;
|
|
if lChanged then begin // Avoid loosing $(macros)
|
|
CompilerComboBox.Text := lFileName;
|
|
UpdateCompilerNote;
|
|
end;
|
|
end;
|
|
|
|
procedure TInitialSetupDialog.FormDestroy(Sender: TObject);
|
|
var
|
|
d: TSDFilenameType;
|
|
begin
|
|
IdleConnected:=false;
|
|
if Assigned(fSearchFpcSourceThread) then begin
|
|
fSearchFpcSourceThread.Terminate;
|
|
fSearchFpcSourceThread.WaitFor;
|
|
end;
|
|
for d:=low(FCandidates) to high(FCandidates) do
|
|
FreeAndNil(FCandidates[d]);
|
|
FreeAndNil(FHeadGraphic);
|
|
end;
|
|
|
|
procedure TInitialSetupDialog.FPCSrcDirBrowseButtonClick(Sender: TObject);
|
|
var
|
|
Dir: String;
|
|
begin
|
|
Dir:=SelectDirectory(lisSelectFPCSourceDirectory, FPCSrcDirComboBox.Text,eopFPCSourceDirectory);
|
|
if Dir='' then
|
|
exit;
|
|
FPCSrcDirComboBox.Text:=Dir;
|
|
UpdateFPCSrcDirNote;
|
|
end;
|
|
|
|
procedure TInitialSetupDialog.FPCSrcDirComboBoxChange(Sender: TObject);
|
|
begin
|
|
UpdateFPCSrcDirNote;
|
|
end;
|
|
|
|
procedure TInitialSetupDialog.LazDirBrowseButtonClick(Sender: TObject);
|
|
var
|
|
Dir: String;
|
|
begin
|
|
Dir:=SelectDirectory(lisSelectLazarusSourceDirectory,LazDirComboBox.Text,eopLazarusDirectory);
|
|
if Dir='' then
|
|
exit;
|
|
LazDirComboBox.Text:=Dir;
|
|
UpdateLazDirNote;
|
|
end;
|
|
|
|
procedure TInitialSetupDialog.LazDirComboBoxChange(Sender: TObject);
|
|
begin
|
|
UpdateLazDirNote;
|
|
end;
|
|
|
|
procedure TInitialSetupDialog.MakeExeBrowseButtonClick(Sender: TObject);
|
|
var
|
|
lExpandedName: string; // Expanded name before Dialog
|
|
lDirName, lFileName: string;
|
|
lTitle: string;
|
|
lChanged: boolean=False;
|
|
Dlg: TIDEOpenDialog;
|
|
Filter: String;
|
|
|
|
begin
|
|
Dlg := IDEOpenDialogClass.Create(nil);
|
|
try
|
|
lTitle := 'make'+GetExecutableExt;
|
|
Dlg.Title := SimpleFormat(lisSelectPathTo, [lTitle]);
|
|
lExpandedName := EnvironmentOptions.GetParsedValue(eopMakeFilename, MakeExeComboBox.Text);
|
|
lDirName := GetValidDirectory(lExpandedName, {out} lFileName);
|
|
Dlg.Options := Dlg.Options+[ofFileMustExist];
|
|
if lFileName='' then
|
|
lFileName := lTitle;
|
|
Filter := dlgFilterAll+'|'+GetAllFilesMask;
|
|
if ExtractFileExt(lFileName)<>'' then
|
|
Filter := dlgFilterExecutable+'|*'+ExtractFileExt(lFileName)+'|'+Filter;
|
|
Dlg.Filter := Filter;
|
|
Dlg.InitialDir := lDirName;
|
|
Dlg.FileName := lFileName;
|
|
if not Dlg.Execute then
|
|
exit;
|
|
lFileName := CleanAndExpandFilename(Dlg.Filename);
|
|
lChanged := UpperCase(lExpandedName)<>UpperCase(lFileName);
|
|
finally
|
|
Dlg.Free;
|
|
end;
|
|
if lChanged then begin // Avoid loosing $(macros)
|
|
MakeExeComboBox.Text := lFileName;
|
|
UpdateMakeExeNote;
|
|
end;
|
|
end;
|
|
|
|
procedure TInitialSetupDialog.MakeExeComboBoxChange(Sender: TObject);
|
|
begin
|
|
UpdateMakeExeNote;
|
|
end;
|
|
|
|
procedure TInitialSetupDialog.OnAppActivate(Sender: TObject);
|
|
begin
|
|
// switched back from another application
|
|
InvalidateFileStateCache;
|
|
end;
|
|
|
|
procedure TInitialSetupDialog.PropertiesPageControlChange(Sender: TObject);
|
|
var
|
|
i: Integer;
|
|
t: PtrInt;
|
|
begin
|
|
if PropertiesPageControl.ActivePage=nil then exit;
|
|
t:=PropertiesPageControl.ActivePage.tag;
|
|
for i:=0 to PropertiesTreeView.Items.TopLvlCount-1 do
|
|
if PtrUInt(PropertiesTreeView.Items.TopLvlItems[i])=t then
|
|
SelectPage(PropertiesTreeView.Items.TopLvlItems[i], True);
|
|
end;
|
|
|
|
procedure TInitialSetupDialog.PropertiesTreeViewSelectionChanged(Sender: TObject);
|
|
begin
|
|
if PropertiesTreeView.Selected=nil then
|
|
SelectPage(TVNodeLazarus)
|
|
else
|
|
SelectPage(PropertiesTreeView.Selected, True);
|
|
end;
|
|
|
|
procedure TInitialSetupDialog.StartIDEBitBtnClick(Sender: TObject);
|
|
var
|
|
Node: TTreeNode;
|
|
s: String;
|
|
MsgResult: TModalResult;
|
|
i: Integer;
|
|
begin
|
|
Node:=FirstErrorNode;
|
|
s:='';
|
|
if Node=TVNodeLazarus then
|
|
s:=lisWithoutAProperLazarusDirectoryYouWillGetALotOfWarn
|
|
else if Node=TVNodeCompiler then
|
|
s:=lisWithoutAProperCompilerTheCodeBrowsingAndCompilingW
|
|
else if Node=TVNodeFPCSources then
|
|
s:=lisWithoutTheProperFPCSourcesCodeBrowsingAndCompletio
|
|
else if Node=TVNodeMakeExe then
|
|
s:=lisWithoutAProperMakeExecutableTheCompilingOfTheIDEIs
|
|
else if Node=TVNodeDebugger then
|
|
s:=lisWithoutAProperDebuggerDebuggingWillBeDisappointing;
|
|
if s<>'' then begin
|
|
MsgResult:=MessageDlg(lisCCOWarningCaption, s, mtWarning, [mbIgnore,
|
|
mbCancel], 0);
|
|
if MsgResult<>mrIgnore then exit;
|
|
end;
|
|
|
|
s:=LazDirComboBox.Text;
|
|
if s<>'' then
|
|
EnvironmentOptions.LazarusDirectory:=s;
|
|
s:=CompilerComboBox.Text;
|
|
if s<>'' then
|
|
EnvironmentOptions.CompilerFilename:=s;
|
|
s:=FPCSrcDirComboBox.Text;
|
|
if s<>'' then
|
|
EnvironmentOptions.FPCSourceDirectory:=s;
|
|
s:=MakeExeComboBox.Text;
|
|
if s<>'' then
|
|
EnvironmentOptions.MakeFilename:=s;
|
|
FInitDebuggerFrame.ApplySelection;
|
|
for i := 0 to SetupDlgFrameList.Count - 1 do
|
|
SetupDlgFrameList[i].ApplySelection;
|
|
ModalResult:=mrOk;
|
|
end;
|
|
|
|
procedure TInitialSetupDialog.StopScanButtonClick(Sender: TObject);
|
|
begin
|
|
if fSearchFpcSourceThread<>nil then
|
|
fSearchFpcSourceThread.Terminate;
|
|
end;
|
|
|
|
procedure TInitialSetupDialog.WelcomePaintBoxPaint(Sender: TObject);
|
|
begin
|
|
with WelcomePaintBox.Canvas do begin
|
|
GradientFill(WelcomePaintBox.ClientRect,$854b32,$c88e60,gdHorizontal);
|
|
Draw(0,WelcomePaintBox.ClientHeight-FHeadGraphic.Height,FHeadGraphic);
|
|
Font.Color:=clWhite;
|
|
Font.Height:=30;
|
|
Brush.Style:=bsClear;
|
|
TextOut(FHeadGraphic.Width+15, 5, lisConfigureLazarusIDE);
|
|
end;
|
|
end;
|
|
|
|
procedure TInitialSetupDialog.OnIdle(Sender: TObject; var Done: Boolean);
|
|
var
|
|
f: Boolean;
|
|
i: Integer;
|
|
begin
|
|
f := FFlags <> [];
|
|
if sdfCompilerFilenameNeedsUpdate in FFlags then begin
|
|
UpdateCompilerFilenameCandidates;
|
|
UpdateCompilerNote;
|
|
end else if sdfFPCSrcDirNeedsUpdate in FFlags then begin
|
|
UpdateFPCSrcDirCandidates;
|
|
UpdateFPCSrcDirNote;
|
|
end else if sdfMakeExeFilenameNeedsUpdate in FFlags then begin
|
|
UpdateMakeExeCandidates;
|
|
UpdateMakeExeNote;
|
|
end else if sdfDebuggerFilenameNeedsUpdate in FFlags then begin
|
|
DoDbgFrameStateChanged(FInitDebuggerFrame.UpdateState);
|
|
Exclude(FFlags,sdfDebuggerFilenameNeedsUpdate);
|
|
IdleConnected:=True;
|
|
end else if sdfFppkgConfigFileNeedsUpdate in FFlags then begin
|
|
fLastParsedFppkgConfigFile := ' ';
|
|
UpdateFppkgCandidates;
|
|
UpdateFppkgNote;
|
|
end else
|
|
IdleConnected:=false;
|
|
|
|
if f then begin
|
|
for i := 0 to SetupDlgFrameList.Count - 1 do
|
|
SetupDlgFrameList[i].UpdateState;
|
|
end;
|
|
end;
|
|
|
|
procedure TInitialSetupDialog.UpdateCaptions;
|
|
begin
|
|
Caption:=SimpleFormat(lisWelcomeToLazarusIDE, [LazarusVersionStr]);
|
|
|
|
StartIDEBitBtn.Caption:=lisStartIDE;
|
|
|
|
LazarusTabSheet.Caption:='Lazarus';
|
|
CompilerTabSheet.Caption:=lisCompiler;
|
|
FPCSourcesTabSheet.Caption:=lisFPCSources;
|
|
MakeExeTabSheet.Caption:='Make';
|
|
DebuggerTabSheet.Caption:=lisDebugger;
|
|
FppkgTabSheet.Caption:='Fppkg';
|
|
|
|
TVNodeLazarus.Text:=LazarusTabSheet.Caption;
|
|
TVNodeCompiler.Text:=CompilerTabSheet.Caption;
|
|
TVNodeFPCSources.Text:=FPCSourcesTabSheet.Caption;
|
|
TVNodeMakeExe.Text:=MakeExeTabSheet.Caption;
|
|
TVNodeDebugger.Text:=DebuggerTabSheet.Caption;
|
|
if TVNodeFppkg<>nil then
|
|
TVNodeFppkg.Text:=FppkgTabSheet.Caption;
|
|
|
|
LazDirBrowseButton.Caption:=lisPathEditBrowse;
|
|
LazDirLabel.Caption:=SimpleFormat(
|
|
lisTheLazarusDirectoryContainsTheSourcesOfTheIDEAndTh, [PathDelim]);
|
|
|
|
FppkgLabel.Caption:=lisFppkgConfiguration;
|
|
FppkgBrowseButton.Caption:=lisPathEditBrowse;
|
|
FppkgWriteConfigButton.Caption:=lisCreateFppkgConfig;
|
|
|
|
CompilerBrowseButton.Caption:=lisPathEditBrowse;
|
|
CompilerLabel.Caption:=SimpleFormat(lisTheFreePascalCompilerExecutableTypicallyHasTheName,
|
|
[DefineTemplates.GetDefaultCompilerFilename,
|
|
DefineTemplates.GetDefaultCompilerFilename(GetCompiledTargetCPU)]);
|
|
|
|
FPCSrcDirBrowseButton.Caption:=lisPathEditBrowse;
|
|
FPCSrcDirLabel.Caption:=SimpleFormat(lisTheSourcesOfTheFreePascalPackagesAreRequiredForBro,
|
|
[GetForcedPathDelims('rtl/linux/system.pp')]);
|
|
ScanLabel.Caption := lisScanning;
|
|
StopScanButton.Caption:=lisStop;
|
|
|
|
MakeExeBrowseButton.Caption:=lisPathEditBrowse;
|
|
MakeExeLabel.Caption:=SimpleFormat(
|
|
lisTheMakeExecutableTypicallyHasTheName, ['make'+GetExecutableExt('')]);
|
|
end;
|
|
|
|
procedure TInitialSetupDialog.DoDbgFrameStateChanged(AState: TSDFilenameQuality
|
|
);
|
|
var
|
|
ImageIndex: Integer;
|
|
begin
|
|
ImageIndex:=QualityToImgIndex(AState);
|
|
TVNodeDebugger.ImageIndex:=ImageIndex;
|
|
TVNodeDebugger.SelectedIndex:=ImageIndex;
|
|
end;
|
|
|
|
procedure TInitialSetupDialog.FrameStateChanged(AnSender: ISetupDlgFrame;
|
|
AState: TInitSetupDlgFrameState; AnAction: TInitSetupDlgFrameAction);
|
|
var
|
|
ImageIndex, i, j: Integer;
|
|
nd: TTreeNode;
|
|
info, info2: TSetupFrameInfo;
|
|
begin
|
|
i := FSetupDlgFrameMap.IndexOf(Pointer(AnSender));
|
|
if i < 0 then exit;
|
|
info := FSetupDlgFrameMap.Data[i];
|
|
nd := info.Node;
|
|
|
|
info.State := AState;
|
|
info.Action := AnAction;
|
|
FSetupDlgFrameMap.Data[i] := info;
|
|
|
|
if info.Group <> '' then begin
|
|
for j := 0 to FSetupDlgFrameMap.Count - 1 do begin
|
|
info2 := FSetupDlgFrameMap.Data[j];
|
|
if (info2.Group = info.Group) then begin
|
|
if (info2.State > AState) then AState := info2.State;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
ImageIndex := -1;
|
|
case AState of
|
|
issOk: ImageIndex := -1;
|
|
issInfo: ImageIndex := ImgIDInfo;
|
|
issHint: ImageIndex := ImgIDHint;
|
|
issNote: ImageIndex := ImgIDNote;
|
|
issWarning: ImageIndex := ImgIDWarning;
|
|
issError: ImageIndex := ImgIDError;
|
|
issFatal: ImageIndex := ImgIDFatal;
|
|
end;
|
|
|
|
|
|
nd.ImageIndex:=ImageIndex;
|
|
nd.SelectedIndex:=ImageIndex;
|
|
end;
|
|
|
|
procedure TInitialSetupDialog.SetGroupCaption(AGroupId, AName: String);
|
|
var
|
|
GrpIdx: Integer;
|
|
GrpInfo: TSetupFrameInfo;
|
|
begin
|
|
GrpIdx := FSetupDlgGroupMap.IndexOf(AGroupId);
|
|
if GrpIdx >= 0 then begin
|
|
GrpInfo := FSetupDlgGroupMap.Data[GrpIdx];
|
|
GrpInfo.Page.Caption := AName;
|
|
GrpInfo.Node.Text := AName;
|
|
end;
|
|
end;
|
|
|
|
procedure TInitialSetupDialog.SelectPage(const ATreeNode: TTreeNode; AnUserSelect: Boolean);
|
|
var
|
|
i: Integer;
|
|
Node: TTreeNode;
|
|
info: TSetupFrameInfo;
|
|
begin
|
|
if FSelectingPage then exit;
|
|
FSelectingPage:=true;
|
|
try
|
|
for i:=0 to PropertiesTreeView.Items.TopLvlCount-1 do begin
|
|
Node:=PropertiesTreeView.Items.TopLvlItems[i];
|
|
if Node=ATreeNode then begin
|
|
PropertiesTreeView.Selected:=Node;
|
|
break;
|
|
end;
|
|
end;
|
|
for i:=0 to PropertiesPageControl.PageCount-1 do begin
|
|
if PropertiesPageControl.Pages[i].Tag=PtrUInt(ATreeNode) then begin
|
|
PropertiesPageControl.ActivePageIndex:=i;
|
|
break;
|
|
end;
|
|
end;
|
|
|
|
for i := 0 to FSetupDlgFrameMap.Count - 1 do begin
|
|
info := FSetupDlgFrameMap.Data[i];
|
|
if info.Node = ATreeNode then
|
|
ISetupDlgFrame(FSetupDlgFrameMap.Keys[i]).PageSelected(AnUserSelect);
|
|
end;
|
|
finally
|
|
FSelectingPage:=false;
|
|
end;
|
|
end;
|
|
|
|
function TInitialSetupDialog.SelectDirectory(aTitle: string): string;
|
|
var
|
|
DirDlg: TSelectDirectoryDialog;
|
|
begin
|
|
Result:='';
|
|
DirDlg:=TSelectDirectoryDialog.Create(nil);
|
|
try
|
|
DirDlg.Title:=aTitle;
|
|
DirDlg.Options:=DirDlg.Options+[ofPathMustExist,ofFileMustExist];
|
|
if not DirDlg.Execute then exit;
|
|
Result:=DirDlg.FileName;
|
|
finally
|
|
DirDlg.Free;
|
|
end;
|
|
end;
|
|
|
|
function TInitialSetupDialog.SelectDirectory(aTitle: string;
|
|
aPathFileName: string; aEnvOptParseType: TEnvOptParseType): string;
|
|
var
|
|
DirDlg: TSelectDirectoryDialog;
|
|
lCurDirName: string;
|
|
lDirPath: string;
|
|
lDirName: string;
|
|
begin
|
|
Result := '';
|
|
if aPathFileName='' then
|
|
case aEnvOptParseType of
|
|
eopLazarusDirectory: lDirPath := EnvironmentOptions.GetParsedLazarusDirectory;
|
|
eopFPCSourceDirectory: lDirPath := EnvironmentOptions.GetParsedFPCSourceDirectory;
|
|
end
|
|
else
|
|
lDirPath := EnvironmentOptions.GetParsedValue(eopLazarusDirectory, aPathFileName);
|
|
lCurDirName := CleanAndExpandFilename(ExcludeTrailingBackSlash(lDirPath));
|
|
lDirPath := GetValidDirectoryAndFilename(lCurDirName, {out} lDirName);
|
|
lDirPath := ExcludeTrailingBackSlash(lDirPath);
|
|
DirDlg := TSelectDirectoryDialog.Create(nil);
|
|
try
|
|
DirDlg.Title := aTitle;
|
|
DirDlg.InitialDir := lDirPath;
|
|
DirDlg.FileName := lDirName;
|
|
DirDlg.Options := DirDlg.Options + [ofExtensionDifferent, ofPathMustExist];
|
|
if DirDlg.Execute then begin
|
|
lDirName := CleanAndExpandFilename(DirDlg.FileName);
|
|
if UpperCase(lCurDirName)<>UpperCase(lDirName) then
|
|
Result := lDirName;
|
|
end;
|
|
finally
|
|
DirDlg.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TInitialSetupDialog.StartFPCSrcThread;
|
|
begin
|
|
fSearchFpcSourceThread:=TSearchFpcSourceThread.Create(Self);
|
|
fSearchFpcSourceThread.OnTerminate:=@ThreadTerminated;
|
|
fSearchFpcSourceThread.fFPCVer:=GetFPCVer;
|
|
ShowHideScanControls(True); // Show scan controls while thread is running
|
|
fSearchFpcSourceThread.Start;
|
|
end;
|
|
|
|
procedure TInitialSetupDialog.UpdateLazarusDirCandidates;
|
|
var
|
|
Dirs: TSDFileInfoList;
|
|
begin
|
|
Dirs:=SearchLazarusDirectoryCandidates(false);
|
|
FreeAndNil(FCandidates[sddtLazarusSrcDir]);
|
|
FCandidates[sddtLazarusSrcDir]:=Dirs;
|
|
FillComboboxWithFileInfoList(LazDirComboBox,Dirs);
|
|
end;
|
|
|
|
procedure TInitialSetupDialog.UpdateCompilerFilenameCandidates;
|
|
var
|
|
Files: TSDFileInfoList;
|
|
begin
|
|
Exclude(FFlags,sdfCompilerFilenameNeedsUpdate);
|
|
Files:=SearchFPCExeCandidates(false,CodeToolBoss.CompilerDefinesCache.TestFilename);
|
|
FreeAndNil(FCandidates[sddtCompilerFilename]);
|
|
FCandidates[sddtCompilerFilename]:=Files;
|
|
FillComboboxWithFileInfoList(CompilerComboBox,Files);
|
|
end;
|
|
|
|
procedure TInitialSetupDialog.UpdateFPCSrcDirCandidates;
|
|
var
|
|
Dirs: TSDFileInfoList;
|
|
begin
|
|
Exclude(FFlags,sdfFPCSrcDirNeedsUpdate);
|
|
Dirs:=SearchFPCSrcDirCandidates(false,GetFPCVer);
|
|
FreeAndNil(FCandidates[sddtFPCSrcDir]);
|
|
FCandidates[sddtFPCSrcDir]:=Dirs;
|
|
FillComboboxWithFileInfoList(FPCSrcDirComboBox,Dirs);
|
|
end;
|
|
|
|
procedure TInitialSetupDialog.UpdateFPCSrcDirCandidate(aFPCSrcDirInfo: TSDFileInfo);
|
|
var
|
|
Dirs: TSDFileInfoList;
|
|
begin
|
|
Exclude(FFlags,sdfFPCSrcDirNeedsUpdate);
|
|
FreeAndNil(FCandidates[sddtFPCSrcDir]);
|
|
Dirs:=TSDFileInfoList.Create;
|
|
Dirs.Add(aFPCSrcDirInfo);
|
|
FCandidates[sddtFPCSrcDir]:=Dirs;
|
|
FillComboboxWithFileInfoList(FPCSrcDirComboBox,Dirs);
|
|
end;
|
|
|
|
procedure TInitialSetupDialog.UpdateMakeExeCandidates(aStopIfFits: boolean);
|
|
var
|
|
Files: TSDFileInfoList;
|
|
begin
|
|
Exclude(FFlags,sdfMakeExeFilenameNeedsUpdate);
|
|
Files:=SearchMakeExeCandidates(aStopIfFits);
|
|
FreeAndNil(FCandidates[sddtMakeExeFileName]);
|
|
FCandidates[sddtMakeExeFileName]:=Files;
|
|
FillComboboxWithFileInfoList(MakeExeComboBox,Files);
|
|
end;
|
|
|
|
procedure TInitialSetupDialog.FillComboboxWithFileInfoList(ABox: TComboBox;
|
|
List: TSDFileInfoList; ItemIndex: integer);
|
|
var
|
|
sl: TStringList;
|
|
i: Integer;
|
|
begin
|
|
sl:=TStringList.Create;
|
|
try
|
|
if List<>nil then
|
|
for i:=0 to List.Count-1 do
|
|
sl.Add(TSDFileInfo(List[i]).Caption);
|
|
ABox.Items.Assign(sl);
|
|
if (ItemIndex>=0) and (ItemIndex<sl.Count) then
|
|
ABox.Text:=sl[ItemIndex]
|
|
else if ABox.Text=ABox.Name then
|
|
ABox.Text:='';
|
|
finally
|
|
sl.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TInitialSetupDialog.SetIdleConnected(const AValue: boolean);
|
|
begin
|
|
if FIdleConnected=AValue then exit;
|
|
FIdleConnected:=AValue;
|
|
if IdleConnected then
|
|
Application.AddOnIdleHandler(@OnIdle)
|
|
else
|
|
Application.RemoveOnIdleHandler(@OnIdle);
|
|
end;
|
|
|
|
procedure TInitialSetupDialog.UpdateLazDirNote;
|
|
var
|
|
CurCaption: String;
|
|
Note: string;
|
|
Quality: TSDFilenameQuality;
|
|
s: String;
|
|
ImageIndex: Integer;
|
|
begin
|
|
if csDestroying in ComponentState then exit;
|
|
CurCaption:=LazDirComboBox.Text;
|
|
CurCaption:=ChompPathDelim(CurCaption);
|
|
EnvironmentOptions.LazarusDirectory:=CurCaption;
|
|
if FLastParsedLazDir=EnvironmentOptions.GetParsedLazarusDirectory then exit;
|
|
FLastParsedLazDir:=EnvironmentOptions.GetParsedLazarusDirectory;
|
|
//debugln(['TInitialSetupDialog.UpdateLazDirNote ',FLastParsedLazDir]);
|
|
Quality:=CheckLazarusDirectoryQuality(FLastParsedLazDir,Note);
|
|
case Quality of
|
|
sddqInvalid: s:=lisError;
|
|
sddqCompatible: s:='';
|
|
else s:=lisWarning;
|
|
end;
|
|
if EnvironmentOptions.LazarusDirectory<>EnvironmentOptions.GetParsedLazarusDirectory
|
|
then
|
|
s:=lisDirectory+EnvironmentOptions.GetParsedLazarusDirectory+LineEnding+
|
|
LineEnding+s;
|
|
LazDirMemo.Text:=s+Note;
|
|
|
|
ImageIndex:=QualityToImgIndex(Quality);
|
|
TVNodeLazarus.ImageIndex:=ImageIndex;
|
|
TVNodeLazarus.SelectedIndex:=ImageIndex;
|
|
|
|
FFlags:=FFlags+[sdfCompilerFilenameNeedsUpdate,sdfFPCSrcDirNeedsUpdate,
|
|
sdfMakeExeFilenameNeedsUpdate,sdfDebuggerFilenameNeedsUpdate];
|
|
IdleConnected:=true;
|
|
end;
|
|
|
|
procedure TInitialSetupDialog.UpdateCompilerNote(aQuiet: boolean);
|
|
var
|
|
CurCaption, ParsedC, Note, s: String;
|
|
Quality: TSDFilenameQuality;
|
|
ImageIndex: Integer;
|
|
CfgCache: TPCTargetConfigCache;
|
|
begin
|
|
if csDestroying in ComponentState then exit;
|
|
CurCaption:=CompilerComboBox.Text;
|
|
EnvironmentOptions.CompilerFilename:=CurCaption;
|
|
ParsedC:=EnvironmentOptions.GetParsedCompilerFilename;
|
|
if fLastParsedCompiler=ParsedC then exit;
|
|
fLastParsedCompiler:=ParsedC;
|
|
Quality:=CheckFPCExeQuality(fLastParsedCompiler,Note,
|
|
CodeToolBoss.CompilerDefinesCache.TestFilename);
|
|
if Quality=sddqCompatible then
|
|
begin
|
|
// check compiler again
|
|
CfgCache:=CodeToolBoss.CompilerDefinesCache.ConfigCaches.Find(
|
|
fLastParsedCompiler,true);
|
|
CfgCache.CompilerDate:=0; // force update
|
|
if CfgCache.NeedsUpdate then
|
|
CfgCache.Update(CodeToolBoss.CompilerDefinesCache.TestFilename);
|
|
BuildBoss.SetBuildTargetIDE(aQuiet);
|
|
end;
|
|
case Quality of
|
|
sddqInvalid: s:=lisError;
|
|
sddqCompatible: s:='';
|
|
else s:=lisWarning;
|
|
end;
|
|
ParsedC:=EnvironmentOptions.GetParsedCompilerFilename;
|
|
if EnvironmentOptions.CompilerFilename<>ParsedC then
|
|
s:=lisFile2+ParsedC+LineEnding+LineEnding+s;
|
|
CompilerMemo.Text:=s+Note;
|
|
|
|
ImageIndex:=QualityToImgIndex(Quality);
|
|
TVNodeCompiler.ImageIndex:=ImageIndex;
|
|
TVNodeCompiler.SelectedIndex:=ImageIndex;
|
|
|
|
FFlags:=FFlags+[sdfFPCSrcDirNeedsUpdate,
|
|
sdfMakeExeFilenameNeedsUpdate,sdfDebuggerFilenameNeedsUpdate];
|
|
if FppkgTabSheet.TabVisible then
|
|
Include(FFlags,sdfFppkgConfigFileNeedsUpdate);
|
|
IdleConnected:=true;
|
|
end;
|
|
|
|
procedure TInitialSetupDialog.UpdateFPCSrcDirNote;
|
|
var
|
|
CurCaption: String;
|
|
Note: string;
|
|
Quality: TSDFilenameQuality;
|
|
s: String;
|
|
ImageIndex: Integer;
|
|
begin
|
|
if csDestroying in ComponentState then exit;
|
|
CurCaption:=FPCSrcDirComboBox.Text;
|
|
CurCaption:=ChompPathDelim(CurCaption);
|
|
EnvironmentOptions.FPCSourceDirectory:=CurCaption;
|
|
if fLastParsedFPCSrcDir=EnvironmentOptions.GetParsedFPCSourceDirectory then exit;
|
|
fLastParsedFPCSrcDir:=EnvironmentOptions.GetParsedFPCSourceDirectory;
|
|
//debugln(['TInitialSetupDialog.UpdateFPCSrcDirNote ',fLastParsedFPCSrcDir]);
|
|
Quality:=CheckFPCSrcDirQuality(fLastParsedFPCSrcDir,Note,GetFPCVer);
|
|
case Quality of
|
|
sddqInvalid: s:=lisError;
|
|
sddqCompatible: s:='';
|
|
else s:=lisWarning;
|
|
end;
|
|
if EnvironmentOptions.FPCSourceDirectory<>EnvironmentOptions.GetParsedFPCSourceDirectory
|
|
then
|
|
s:=lisDirectory+EnvironmentOptions.GetParsedFPCSourceDirectory+LineEnding+
|
|
LineEnding+s;
|
|
s+=Note;
|
|
if Quality<>sddqCompatible then
|
|
s+=#13+lisYouCanDownloadFPCAndTheFPCSourcesFromHttpSourcefor;
|
|
FPCSrcDirMemo.Text:=s;
|
|
|
|
ImageIndex:=QualityToImgIndex(Quality);
|
|
TVNodeFPCSources.ImageIndex:=ImageIndex;
|
|
TVNodeFPCSources.SelectedIndex:=ImageIndex;
|
|
end;
|
|
|
|
procedure TInitialSetupDialog.UpdateMakeExeNote;
|
|
var
|
|
CurCaption: String;
|
|
Note: string;
|
|
Quality: TSDFilenameQuality;
|
|
s: String;
|
|
ImageIndex: Integer;
|
|
begin
|
|
if csDestroying in ComponentState then exit;
|
|
CurCaption:=MakeExeComboBox.Text;
|
|
EnvironmentOptions.MakeFilename:=CurCaption;
|
|
if fLastParsedMakeExe=EnvironmentOptions.GetParsedMakeFilename then exit;
|
|
fLastParsedMakeExe:=EnvironmentOptions.GetParsedMakeFilename;
|
|
//debugln(['TInitialSetupDialog.UpdateMakeExeNote ',fLastParsedMakeExe]);
|
|
Quality:=CheckMakeExeQuality(fLastParsedMakeExe,Note);
|
|
|
|
case Quality of
|
|
sddqInvalid: s:=lisError;
|
|
sddqCompatible: s:='';
|
|
else s:=lisWarning;
|
|
end;
|
|
if EnvironmentOptions.MakeFilename<>EnvironmentOptions.GetParsedMakeFilename
|
|
then
|
|
s:=lisFile2+EnvironmentOptions.GetParsedMakeFilename+LineEnding+
|
|
LineEnding+s;
|
|
MakeExeMemo.Text:=s+Note;
|
|
|
|
ImageIndex:=QualityToImgIndex(Quality);
|
|
TVNodeMakeExe.ImageIndex:=ImageIndex;
|
|
TVNodeMakeExe.SelectedIndex:=ImageIndex;
|
|
|
|
IdleConnected:=true;
|
|
end;
|
|
|
|
function TInitialSetupDialog.FirstErrorNode: TTreeNode;
|
|
var
|
|
i: Integer;
|
|
begin
|
|
for i:=0 to PropertiesTreeView.Items.TopLvlCount-1 do
|
|
begin
|
|
Result:=PropertiesTreeView.Items.TopLvlItems[i];
|
|
if Result.ImageIndex=ImgIDFatal then exit;
|
|
end;
|
|
for i:=0 to PropertiesTreeView.Items.TopLvlCount-1 do
|
|
begin
|
|
Result:=PropertiesTreeView.Items.TopLvlItems[i];
|
|
if Result.ImageIndex=ImgIDError then exit;
|
|
end;
|
|
Result:=FirstWarningNode;
|
|
end;
|
|
|
|
function TInitialSetupDialog.FirstWarningNode: TTreeNode;
|
|
var
|
|
i: Integer;
|
|
begin
|
|
for i:=0 to PropertiesTreeView.Items.TopLvlCount-1 do
|
|
begin
|
|
Result:=PropertiesTreeView.Items.TopLvlItems[i];
|
|
if Result.ImageIndex=ImgIDWarning then
|
|
exit;
|
|
end;
|
|
for i:=0 to PropertiesTreeView.Items.TopLvlCount-1 do
|
|
begin
|
|
Result:=PropertiesTreeView.Items.TopLvlItems[i];
|
|
if Result.ImageIndex=ImgIDNote then
|
|
exit;
|
|
end;
|
|
for i:=0 to PropertiesTreeView.Items.TopLvlCount-1 do
|
|
begin
|
|
Result:=PropertiesTreeView.Items.TopLvlItems[i];
|
|
if Result.ImageIndex=ImgIDHint then
|
|
exit;
|
|
end;
|
|
for i:=0 to PropertiesTreeView.Items.TopLvlCount-1 do
|
|
begin
|
|
Result:=PropertiesTreeView.Items.TopLvlItems[i];
|
|
if Result.ImageIndex=ImgIDInfo then
|
|
exit;
|
|
end;
|
|
Result:=nil;
|
|
end;
|
|
|
|
function TInitialSetupDialog.GetFirstCandidate(Candidates: TSDFileInfoList;
|
|
MinQuality: TSDFilenameQuality): TSDFileInfo;
|
|
var
|
|
i: Integer;
|
|
begin
|
|
if Candidates<>nil then
|
|
for i:=0 to Candidates.Count-1 do begin
|
|
Result:=TSDFileInfo(Candidates[i]);
|
|
if Result.Quality>=MinQuality then
|
|
exit;
|
|
end;
|
|
Result:=nil;
|
|
end;
|
|
|
|
function TInitialSetupDialog.QualityToImgIndex(Quality: TSDFilenameQuality): integer;
|
|
begin
|
|
if Quality=sddqCompatible then
|
|
Result:=-1
|
|
else if Quality=sddqWrongMinorVersion then
|
|
Result:=ImgIDWarning
|
|
else if Quality=sddqIncomplete then
|
|
Result:=ImgIDWarning
|
|
else if Quality=sddqMakeNotWithFpc then
|
|
Result:=ImgIDWarning
|
|
else if Quality=sddqHint then
|
|
Result:=ImgIDHint
|
|
else
|
|
Result:=ImgIDError;
|
|
end;
|
|
|
|
procedure TInitialSetupDialog.ShowHideScanControls(aShow: Boolean);
|
|
begin
|
|
// Show ProgressBar and Stop button durin scanning
|
|
ScanLabel.Visible:=aShow;
|
|
ScanProgressBar.Visible:=aShow;
|
|
StopScanButton.Visible:=aShow;
|
|
// At the same time disable other GUI controls so a user can not mess with it
|
|
StartIDEBitBtn.Enabled:=not aShow;
|
|
FPCSrcDirBrowseButton.Enabled:=not aShow;
|
|
FPCSrcDirComboBox.Enabled:=not aShow;
|
|
// FPCSrcDirMemo.Enabled:=not aShow;
|
|
end;
|
|
|
|
procedure TInitialSetupDialog.ThreadTerminated(Sender: TObject);
|
|
begin
|
|
debugln(['TInitialSetupDialog.ThreadTerminated ']);
|
|
fSearchFpcSourceThread:=nil; // Thread will free itself. Make the variable nil, too.
|
|
ShowHideScanControls(false);
|
|
end;
|
|
|
|
procedure TInitialSetupDialog.TranslateResourceStrings;
|
|
begin
|
|
IDETranslations.TranslateResourceStrings(
|
|
EnvironmentOptions.GetParsedLazarusDirectory,
|
|
EnvironmentOptions.LanguageID);
|
|
UpdateCaptions;
|
|
end;
|
|
|
|
constructor TInitialSetupDialog.Create(TheOwner: TComponent);
|
|
begin
|
|
inherited Create(TheOwner);
|
|
FSetupDlgFrameMap := TSetupDlgFrameMap.Create;
|
|
FSetupDlgGroupMap := TGroupMap.Create;
|
|
|
|
FInitDebuggerFrame := TInitDebuggerFrame.Create(Self);
|
|
FInitDebuggerFrame.Parent := DebuggerTabSheet;
|
|
FInitDebuggerFrame.Align := alClient;
|
|
FInitDebuggerFrame.OnStateChanged := @DoDbgFrameStateChanged;
|
|
FInitDebuggerFrame.Init;
|
|
end;
|
|
|
|
destructor TInitialSetupDialog.Destroy;
|
|
var
|
|
i: Integer;
|
|
begin
|
|
for i := 0 to SetupDlgFrameList.Count - 1 do
|
|
SetupDlgFrameList[i].Done;
|
|
|
|
inherited Destroy;
|
|
FSetupDlgFrameMap.Free;
|
|
FSetupDlgGroupMap.Free;
|
|
end;
|
|
|
|
procedure TInitialSetupDialog.Init;
|
|
var
|
|
Node: TTreeNode;
|
|
Candidate: TSDFileInfo;
|
|
IsFirstStart: Boolean;
|
|
PrimaryFilename: String;
|
|
SecondaryFilename: String;
|
|
PrimaryEnvs: TStringList;
|
|
SecondaryEnvs: TStringList;
|
|
i: Integer;
|
|
begin
|
|
IsFirstStart:=not FileExistsCached(EnvironmentOptions.Filename);
|
|
if not IsFirstStart then begin
|
|
IsFirstStart:= False;
|
|
PrimaryFilename:=EnvironmentOptions.Filename;
|
|
SecondaryFilename:=AppendPathDelim(GetSecondaryConfigPath)+ExtractFilename(PrimaryFilename);
|
|
if FileExistsUTF8(PrimaryFilename)
|
|
and FileExistsUTF8(SecondaryFilename) then begin
|
|
// compare content of primary and secondary config
|
|
PrimaryEnvs:=TStringList.Create;
|
|
SecondaryEnvs:=TStringList.Create;
|
|
try
|
|
PrimaryEnvs.LoadFromFile(PrimaryFilename);
|
|
except
|
|
on E: Exception do
|
|
debugln(['TInitialSetupDialog.Init unable to read "'+PrimaryFilename+'": '+E.Message]);
|
|
end;
|
|
try
|
|
SecondaryEnvs.LoadFromFile(SecondaryFilename);
|
|
except
|
|
on E: Exception do
|
|
debugln(['TInitialSetupDialog.Init unable to read "'+SecondaryFilename+'": '+E.Message]);
|
|
end;
|
|
// IsFirstStart:=PrimaryEnvs.Text=SecondaryEnvs.Text;
|
|
PrimaryEnvs.Free;
|
|
SecondaryEnvs.Free;
|
|
end;
|
|
end
|
|
else
|
|
IsFirstStart := True;
|
|
//debugln(['TInitialSetupDialog.Init IsFirstStart=',IsFirstStart,' ',EnvironmentOptions.Filename]);
|
|
|
|
// Lazarus directory
|
|
UpdateLazarusDirCandidates;
|
|
if IsFirstStart
|
|
or (not FileExistsCached(EnvironmentOptions.GetParsedLazarusDirectory))
|
|
then begin
|
|
// first start => choose first best candidate
|
|
Candidate:=GetFirstCandidate(FCandidates[sddtLazarusSrcDir]);
|
|
if Candidate<>nil then
|
|
begin
|
|
EnvironmentOptions.LazarusDirectory:=Candidate.Caption;
|
|
if Candidate.Quality=sddqCompatible then
|
|
TranslateResourceStrings;
|
|
end;
|
|
end;
|
|
LazDirComboBox.Text:=EnvironmentOptions.LazarusDirectory;
|
|
FLastParsedLazDir:='. .';
|
|
UpdateLazDirNote;
|
|
|
|
// compiler filename
|
|
UpdateCompilerFilenameCandidates;
|
|
if IsFirstStart
|
|
or (EnvironmentOptions.CompilerFilename='')
|
|
or (not FileExistsCached(EnvironmentOptions.GetParsedCompilerFilename))
|
|
then begin
|
|
// first start => choose first best candidate
|
|
Candidate:=GetFirstCandidate(FCandidates[sddtCompilerFilename]);
|
|
if Candidate<>nil then
|
|
EnvironmentOptions.CompilerFilename:=Candidate.Caption;
|
|
end;
|
|
CompilerComboBox.Text:=EnvironmentOptions.CompilerFilename;
|
|
fLastParsedCompiler:='. .';
|
|
UpdateCompilerNote;
|
|
|
|
// FPC source directory
|
|
UpdateFPCSrcDirCandidates;
|
|
{$IFDEF DebugSearchFPCSrcThread}
|
|
IsFirstStart:=true;
|
|
{$ENDIF}
|
|
if IsFirstStart or (EnvironmentOptions.FPCSourceDirectory='')
|
|
or (not FileExistsCached(EnvironmentOptions.GetParsedFPCSourceDirectory))
|
|
then begin
|
|
// first start => choose first best candidate
|
|
{$IFDEF DebugSearchFPCSrcThread}
|
|
Candidate:=nil;
|
|
{$ELSE}
|
|
Candidate:=GetFirstCandidate(FCandidates[sddtFPCSrcDir]);
|
|
{$ENDIF}
|
|
if Candidate<>nil then begin
|
|
EnvironmentOptions.FPCSourceDirectory:=Candidate.Caption;
|
|
end
|
|
else begin
|
|
// No candidates found => start a thread to scan the file system.
|
|
{$IFNDEF LCLCarbon}
|
|
// carbon interface does not support Synchronize outside Application.Run
|
|
StartFPCSrcThread;
|
|
SelectPage(TVNodeFPCSources);
|
|
{$ENDIF}
|
|
end;
|
|
end;
|
|
ShowHideScanControls(fSearchFpcSourceThread<>nil);
|
|
FPCSrcDirComboBox.Text:=EnvironmentOptions.FPCSourceDirectory;
|
|
fLastParsedFPCSrcDir:='. .';
|
|
UpdateFPCSrcDirNote;
|
|
|
|
// Make executable
|
|
UpdateMakeExeCandidates({aStopIfFits} True);
|
|
if IsFirstStart
|
|
or (EnvironmentOptions.MakeFilename='')
|
|
or (not FileExistsCached(EnvironmentOptions.GetParsedMakeFilename)) then
|
|
begin
|
|
// first start => choose first best candidate
|
|
Candidate:=GetFirstCandidate(FCandidates[sddtMakeExeFilename]);
|
|
if Candidate<>nil then
|
|
EnvironmentOptions.MakeFilename:=Candidate.Caption
|
|
else begin // second chance => better an incomplete instead of none (especially for windows)
|
|
Candidate:=GetFirstCandidate(FCandidates[sddtMakeExeFilename], sddqIncomplete);
|
|
if Candidate<>nil then
|
|
EnvironmentOptions.MakeFilename:=Candidate.Caption;
|
|
end;
|
|
end;
|
|
MakeExeComboBox.Text:=EnvironmentOptions.MakeFilename;
|
|
fLastParsedMakeExe:='. .';
|
|
UpdateMakeExeNote;
|
|
|
|
// Debugger
|
|
DoDbgFrameStateChanged(FInitDebuggerFrame.UpdateState);
|
|
|
|
// Fppkg
|
|
fLastParsedFppkgConfigFile := ' ';
|
|
if FppkgTabSheet.TabVisible then
|
|
begin
|
|
FppkgComboBox.Text := EnvironmentOptions.FppkgConfigFile;
|
|
UpdateFppkgCandidates;
|
|
UpdateFppkgNote;
|
|
end;
|
|
|
|
for i := 0 to SetupDlgFrameList.Count - 1 do
|
|
SetupDlgFrameList[i].Init;
|
|
for i := 0 to SetupDlgFrameList.Count - 1 do
|
|
SetupDlgFrameList[i].UpdateState;
|
|
|
|
// select first error
|
|
Node:=FirstErrorNode;
|
|
if Node=nil then
|
|
Node:=TVNodeLazarus;
|
|
SelectPage(Node);
|
|
end;
|
|
|
|
procedure TInitialSetupDialog.UpdateFppkgNote;
|
|
var
|
|
CurCaption: String;
|
|
FppkgMsg, Note: string;
|
|
Quality: TSDFilenameQuality;
|
|
ConfigFile: string;
|
|
ImageIndex: Integer;
|
|
begin
|
|
if csDestroying in ComponentState then exit;
|
|
if not FppkgTabSheet.TabVisible then exit;
|
|
CurCaption:=FppkgComboBox.Text;
|
|
EnvironmentOptions.FppkgConfigFile:=CurCaption;
|
|
if fLastParsedFppkgConfigFile=EnvironmentOptions.GetParsedFppkgConfig then exit;
|
|
fLastParsedFppkgConfigFile:=EnvironmentOptions.GetParsedFppkgConfig;
|
|
|
|
ConfigFile := fLastParsedFppkgConfigFile;
|
|
Quality := CheckFppkgConfigFile(ConfigFile, Note);
|
|
if Quality<>sddqCompatible then
|
|
begin
|
|
Note := lisError + Note + LineEnding;
|
|
FppkgWriteConfigButton.Enabled := (Quality=sddqIncomplete);
|
|
end
|
|
else
|
|
begin
|
|
Quality := CheckFppkgConfiguration(ConfigFile, FppkgMsg);
|
|
|
|
if Quality=sddqCompatible then
|
|
begin
|
|
Note := lisOk;
|
|
FppkgWriteConfigButton.Enabled := False;
|
|
end
|
|
else
|
|
begin
|
|
Note := lisError + Format(lisIncorrectFppkgConfiguration, [FppkgMsg]) + LineEnding;
|
|
Note := Note + LineEnding + lisFppkgFixConfiguration;
|
|
FppkgWriteConfigButton.Enabled := True;
|
|
end;
|
|
end;
|
|
|
|
FppkgMemo.Text := lisFile2 + ConfigFile + LineEnding + LineEnding + Note;
|
|
|
|
ImageIndex:=QualityToImgIndex(Quality);
|
|
TVNodeFppkg.ImageIndex:=ImageIndex;
|
|
TVNodeFppkg.SelectedIndex:=ImageIndex;
|
|
|
|
IdleConnected:=true;
|
|
end;
|
|
|
|
procedure TInitialSetupDialog.FppkgComboBoxChange(Sender: TObject);
|
|
begin
|
|
UpdateFppkgNote;
|
|
end;
|
|
|
|
procedure TInitialSetupDialog.UpdateFppkgCandidates;
|
|
|
|
function SearchFppkgFpcPrefixCandidates: TSDFileInfoList;
|
|
|
|
function CheckFile(AFile: string; var List: TSDFileInfoList): boolean;
|
|
var
|
|
Item: TSDFileInfo;
|
|
begin
|
|
Result:=false;
|
|
if AFile='' then exit;
|
|
ForcePathDelims(AFile);
|
|
// check if already checked
|
|
if Assigned(List) and List.CaptionExists(AFile) then exit;
|
|
|
|
if FileExistsUTF8(AFile) then
|
|
begin
|
|
if List=nil then
|
|
List:=TSDFileInfoList.create(true);
|
|
Item:=List.AddNewItem(AFile, AFile);
|
|
Item.Quality:=sddqCompatible;
|
|
Result := True;
|
|
end;
|
|
end;
|
|
begin
|
|
Result:=nil;
|
|
|
|
CheckFile(GetFppkgConfigFile(False, False), Result);
|
|
CheckFile(GetFppkgConfigFile(False, True), Result);
|
|
CheckFile(GetFppkgConfigFile(True, False), Result);
|
|
CheckFile(GetFppkgConfigFile(True, True), Result);
|
|
end;
|
|
|
|
var
|
|
Files: TSDFileInfoList;
|
|
begin
|
|
Exclude(FFlags,sdfFppkgConfigFileNeedsUpdate);
|
|
if not FppkgTabSheet.TabVisible then exit;
|
|
Files:=SearchFppkgFpcPrefixCandidates;
|
|
FreeAndNil(FCandidates[sddtFppkgFpcPrefix]);
|
|
FCandidates[sddtFppkgFpcPrefix]:=Files;
|
|
FillComboboxWithFileInfoList(FppkgComboBox,Files,-1);
|
|
end;
|
|
|
|
procedure TInitialSetupDialog.FppkgBrowseButtonClick(Sender: TObject);
|
|
var
|
|
lExpandedName: string; // Expanded name before Dialog
|
|
lDirName, lFileName: string;
|
|
lTitle: string;
|
|
lChanged: boolean=False;
|
|
Dlg: TIDEOpenDialog;
|
|
Filter: String;
|
|
begin
|
|
if not FppkgTabSheet.TabVisible then exit;
|
|
Dlg:=IDEOpenDialogClass.Create(nil);
|
|
try
|
|
lTitle:='fppkg.cfg';
|
|
Dlg.Title:=SimpleFormat(lisSelectPathTo, [lTitle]);
|
|
lExpandedName:=EnvironmentOptions.GetParsedValue(eopFppkgConfigFile, FppkgComboBox.Text);
|
|
lDirName := GetValidDirectory(lExpandedName, {out} lFileName);
|
|
Dlg.Options:=Dlg.Options+[ofFileMustExist];
|
|
if lFileName='' then
|
|
lFileName:=lTitle;
|
|
Filter:=dlgFilterAll+'|'+GetAllFilesMask;
|
|
if ExtractFileExt(lFileName)<>'' then
|
|
Filter:=dlgFilterExecutable+'|*'+ExtractFileExt(lFileName)+'|'+Filter;
|
|
Dlg.Filter:=Filter;
|
|
Dlg.InitialDir:=lDirName;
|
|
Dlg.FileName:=lFileName;
|
|
if not Dlg.Execute then
|
|
exit;
|
|
lFileName:=CleanAndExpandFilename(Dlg.Filename);
|
|
lChanged := UpperCase(lExpandedName)<>UpperCase(lFileName);
|
|
finally
|
|
Dlg.Free;
|
|
end;
|
|
if lChanged then begin // Avoid loosing $(macros)
|
|
FppkgComboBox.Text:=lFileName;
|
|
UpdateFppkgNote;
|
|
end;
|
|
end;
|
|
|
|
procedure TInitialSetupDialog.FppkgWriteConfigButtonClick(Sender: TObject);
|
|
var
|
|
Dialog: TGenerateFppkgConfigurationDialog;
|
|
begin
|
|
if not FppkgTabSheet.TabVisible then exit;
|
|
Dialog := TGenerateFppkgConfigurationDialog.Create(Self);
|
|
try
|
|
Dialog.Compiler := fLastParsedCompiler;
|
|
if fLastParsedFppkgConfigFile='' then
|
|
Dialog.FppkgCfgFilename := GetFppkgConfigFile(False, False)
|
|
else
|
|
Dialog.FppkgCfgFilename := fLastParsedFppkgConfigFile;
|
|
Dialog.ShowModal;
|
|
finally
|
|
Dialog.Free;
|
|
end;
|
|
|
|
fLastParsedFppkgConfigFile := ' ';
|
|
UpdateFppkgNote;
|
|
end;
|
|
|
|
end.
|
|
|