mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-09 16:28:16 +02:00
792 lines
23 KiB
ObjectPascal
792 lines
23 KiB
ObjectPascal
unit InitialSetupDlgDebuggerFrame;
|
|
|
|
{$mode ObjFPC}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils, Types, Forms, Controls, StdCtrls, ComCtrls, ExtCtrls,
|
|
Dialogs, Buttons, GDBMIDebugger, DbgIntfDebuggerBase, FileUtil, LazFileUtils,
|
|
IDEDialogs, IDEUtils, IDEImagesIntf, FileProcs, FpDebugDebugger,
|
|
{$Ifdef Darwin} FpLldbDebugger, {$ENDIF}
|
|
IdeDebuggerOpts, LazarusIDEStrConsts, InitialSetupProc,
|
|
EnvironmentOpts, LazConf, StrUtils;
|
|
|
|
type
|
|
|
|
TDebuggerIntfClass = class of TDebuggerIntf;
|
|
|
|
TDbgCfgStateChangedEvent = procedure(AState: TSDFilenameQuality) of object;
|
|
|
|
{ TInitDebuggerFrame }
|
|
|
|
TInitDebuggerFrame = class(TFrame)
|
|
btnBrowse: TButton;
|
|
cmbDebuggerName: TComboBox;
|
|
cmbDebuggerPath: TComboBox;
|
|
edDebuggerNotes: TMemo;
|
|
edDebuggerName: TEdit;
|
|
edDebuggerPath: TEdit;
|
|
edDebuggerPathResolved: TEdit;
|
|
GroupBox1: TGroupBox;
|
|
lbAboutDebugger: TLabel;
|
|
lbDebuggerPath: TLabel;
|
|
pnlDbgPath: TPanel;
|
|
PnlSelectDbgPath: TPanel;
|
|
rbCreateNew: TRadioButton;
|
|
rbChange: TRadioButton;
|
|
rbKeep: TRadioButton;
|
|
rbIgnore: TRadioButton;
|
|
rbChangePath: TRadioButton;
|
|
SpeedButton1: TSpeedButton;
|
|
procedure btnBrowseClick(Sender: TObject);
|
|
procedure FrameResize(Sender: TObject);
|
|
procedure rbKeepChange(Sender: TObject);
|
|
procedure SpeedButton1Click(Sender: TObject);
|
|
private
|
|
FCurrentState: TCurrentDebuggerSetupResult;
|
|
FCurDbgCfg: TDebuggerPropertiesConfig;
|
|
FSelDbgCfg: TDebuggerPropertiesConfig; // Selected in combo
|
|
FPathDbgCfg: TDebuggerPropertiesConfig; // Path-Combo currently showing for ...
|
|
|
|
FOnStateChanged: TDbgCfgStateChangedEvent;
|
|
FInChangeLock, FInPathLock: Integer;
|
|
FLastDbgPath, FUserDbgPath: String;
|
|
|
|
function RecommendedClass: TDebuggerIntfClass;
|
|
function CountRecommendedBackend: Integer;
|
|
function RecommendedBackend(AIdx: Integer): TDebuggerPropertiesConfig;
|
|
|
|
function GetVisibleDebuggerClass: TDebuggerIntfClass;
|
|
function GetVisibleDebuggerCfg: TDebuggerPropertiesConfig;
|
|
function GetVisibleDebuggerPath: String;
|
|
function GetVisibleDebuggerDefaultExe: String;
|
|
|
|
function GetCfgDefaultExe(ADbgClass: TDebuggerIntfClass): String;
|
|
function CfgNeedsDebuggerPath(ADbgClass: TDebuggerIntfClass): boolean;
|
|
function GetCfgDefaultExe(ADbgCfg: TDebuggerPropertiesConfig): String;
|
|
function CfgNeedsDebuggerPath(ADbgCfg: TDebuggerPropertiesConfig): boolean;
|
|
function CfgHasBrokenDebuggerPath(ADbgCfg: TDebuggerPropertiesConfig): boolean;
|
|
|
|
procedure ShowCurrentDbgClass;
|
|
procedure ShowRecommentedDbgClass;
|
|
procedure ShowSelectedDbgClass;
|
|
|
|
procedure HideDebuggerPath;
|
|
procedure MaybeShowDebuggerPathForCurrentCfg;
|
|
procedure MaybeShowDebuggerPathCombo(ADbgCfg: TDebuggerPropertiesConfig; ADbgClass: TDebuggerIntfClass = nil);
|
|
procedure MaybeShowDebuggerPathResolved;
|
|
|
|
function GetDebuggerClassNote(out ANote: String): TSDFilenameQuality;
|
|
function GetDebuggerPathNote(out ANote: String): TSDFilenameQuality;
|
|
public
|
|
procedure Init;
|
|
function UpdateState: TSDFilenameQuality;
|
|
procedure ApplySelection;
|
|
|
|
property OnStateChanged: TDbgCfgStateChangedEvent read FOnStateChanged write FOnStateChanged;
|
|
end;
|
|
|
|
implementation
|
|
|
|
{$R *.lfm}
|
|
|
|
const
|
|
resOk = sddqCompatible;
|
|
resHint = sddqHint;
|
|
resWarn = sddqIncomplete;
|
|
resErr = sddqInvalid;
|
|
|
|
NOTES_MIN_HEIGHT = 100;
|
|
|
|
function MaxResult(ARes1, ARes2: TSDFilenameQuality): TSDFilenameQuality;
|
|
begin
|
|
Result := ARes1;
|
|
if (ARes2 = resErr) or
|
|
((ARes2 = resWarn) and (Result in [resHint, resOk])) or
|
|
(Result = resOk)
|
|
then
|
|
Result := ARes2;
|
|
end;
|
|
|
|
{ TInitDebuggerFrame }
|
|
|
|
procedure TInitDebuggerFrame.FrameResize(Sender: TObject);
|
|
begin
|
|
VertScrollBar.Range := edDebuggerNotes.Top + edDebuggerNotes.Constraints.MinHeight;
|
|
VertScrollBar.Page := Height;
|
|
end;
|
|
|
|
procedure TInitDebuggerFrame.btnBrowseClick(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 := GetVisibleDebuggerDefaultExe;
|
|
if lTitle = '' then
|
|
lTitle := '?';
|
|
Dlg.Title := SimpleFormat(lisSelectPathTo, [lTitle]);
|
|
lExpandedName := EnvironmentOptions.GetParsedValue(eopDebuggerFilename, GetVisibleDebuggerPath);
|
|
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 := CompareFilenames(lExpandedName, lFileName) <> 0;
|
|
finally
|
|
Dlg.Free;
|
|
end;
|
|
if lChanged then begin // Avoid looing $(macros)
|
|
cmbDebuggerPath.Text := lFileName;
|
|
rbKeepChange(Sender);
|
|
end;
|
|
end;
|
|
|
|
procedure TInitDebuggerFrame.rbKeepChange(Sender: TObject);
|
|
var
|
|
st: TSDFilenameQuality;
|
|
begin
|
|
if FInChangeLock > 0 then
|
|
exit;
|
|
inc(FInChangeLock);
|
|
try
|
|
if Sender = cmbDebuggerPath then
|
|
inc(FInPathLock);
|
|
|
|
FLastDbgPath := cmbDebuggerPath.Text;
|
|
if (FLastDbgPath <> '') and
|
|
(FUserDbgPath <> FLastDbgPath) and
|
|
(cmbDebuggerPath.Items.IndexOf(FLastDbgPath) < 0)
|
|
then
|
|
FUserDbgPath := FLastDbgPath;
|
|
|
|
if (Sender = cmbDebuggerName) then
|
|
FSelDbgCfg := TDebuggerPropertiesConfig(cmbDebuggerName.Items.Objects[cmbDebuggerName.ItemIndex]);
|
|
|
|
if (Sender = cmbDebuggerName) or (Sender is TRadioButton) then
|
|
FLastDbgPath := '';
|
|
|
|
st := UpdateState;
|
|
finally
|
|
if Sender = cmbDebuggerPath then
|
|
dec(FInPathLock);
|
|
dec(FInChangeLock);
|
|
|
|
if FOnStateChanged <> nil then
|
|
FOnStateChanged(st);
|
|
end;
|
|
end;
|
|
|
|
procedure TInitDebuggerFrame.SpeedButton1Click(Sender: TObject);
|
|
begin
|
|
MessageDlg(Format(
|
|
InitDlgDebugPopupInformation
|
|
, [''+LineEnding, RecommendedClass.Caption]),
|
|
mtInformation, [mbOK], 0
|
|
);
|
|
end;
|
|
|
|
function TInitDebuggerFrame.RecommendedClass: TDebuggerIntfClass;
|
|
begin
|
|
Result := TGDBMIDebugger;
|
|
{$If defined(WINDOWS)}
|
|
Result := TFpDebugDebugger;
|
|
{$ElseIf defined(Linux)}
|
|
Result := TFpDebugDebugger;
|
|
{$ElseIf defined(Darwin)}
|
|
Result := TFpLldbDebugger;
|
|
{$ENDIF}
|
|
if dfNotSuitableForOsArch in Result.SupportedFeatures then
|
|
Result := TGDBMIDebugger;
|
|
end;
|
|
|
|
function TInitDebuggerFrame.CountRecommendedBackend: Integer;
|
|
var
|
|
i: Integer;
|
|
r: TDebuggerIntfClass;
|
|
begin
|
|
Result := 0;
|
|
r := RecommendedClass;
|
|
for i := 0 to DebuggerOptions.DebuggerPropertiesConfigList.Count - 1 do
|
|
if DebuggerOptions.DebuggerPropertiesConfigList.Opt[i].DebuggerClass = r then
|
|
inc(Result);
|
|
end;
|
|
|
|
function TInitDebuggerFrame.RecommendedBackend(AIdx: Integer): TDebuggerPropertiesConfig;
|
|
var
|
|
r: TDebuggerIntfClass;
|
|
i: Integer;
|
|
begin
|
|
Result := nil;
|
|
r := RecommendedClass;
|
|
for i := 0 to DebuggerOptions.DebuggerPropertiesConfigList.Count - 1 do
|
|
if DebuggerOptions.DebuggerPropertiesConfigList.Opt[i].DebuggerClass = r then begin
|
|
if AIdx = 0 then
|
|
exit(DebuggerOptions.DebuggerPropertiesConfigList.Opt[i]);
|
|
dec(AIdx);
|
|
end;
|
|
end;
|
|
|
|
function TInitDebuggerFrame.GetVisibleDebuggerClass: TDebuggerIntfClass;
|
|
var
|
|
c: TDebuggerPropertiesConfig;
|
|
begin
|
|
Result := nil;
|
|
if rbCreateNew.Checked then
|
|
exit(RecommendedClass);
|
|
c := GetVisibleDebuggerCfg;
|
|
if c <> nil then
|
|
Result := c.DebuggerClass;
|
|
end;
|
|
|
|
function TInitDebuggerFrame.GetVisibleDebuggerCfg: TDebuggerPropertiesConfig;
|
|
begin
|
|
Result := nil;
|
|
if rbCreateNew.Checked then
|
|
exit;
|
|
if edDebuggerName.Visible then
|
|
Result := FCurDbgCfg
|
|
else
|
|
if cmbDebuggerName.Visible then
|
|
Result := FSelDbgCfg;
|
|
end;
|
|
|
|
function TInitDebuggerFrame.GetVisibleDebuggerPath: String;
|
|
var
|
|
c: TDebuggerPropertiesConfig;
|
|
begin
|
|
Result := '';
|
|
if (not HandleAllocated) or (not cmbDebuggerPath.HandleAllocated) then begin
|
|
c := GetVisibleDebuggerCfg;
|
|
if c <> nil then
|
|
Result := c.DebuggerFilename;
|
|
exit;
|
|
end;
|
|
if PnlSelectDbgPath.Visible then Result := cmbDebuggerPath.Text
|
|
else
|
|
if edDebuggerPath.Visible then Result := edDebuggerPath.Caption;
|
|
end;
|
|
|
|
function TInitDebuggerFrame.GetVisibleDebuggerDefaultExe: String;
|
|
begin
|
|
Result := GetCfgDefaultExe(GetVisibleDebuggerCfg);
|
|
end;
|
|
|
|
function TInitDebuggerFrame.GetCfgDefaultExe(ADbgClass: TDebuggerIntfClass): String;
|
|
begin
|
|
Result := '';
|
|
if ADbgClass <> nil then begin
|
|
Result := ADbgClass.ExeBaseName;
|
|
if Result <> '' then
|
|
Result := Result + GetExecutableExt;
|
|
end;
|
|
end;
|
|
|
|
function TInitDebuggerFrame.CfgNeedsDebuggerPath(ADbgClass: TDebuggerIntfClass
|
|
): boolean;
|
|
begin
|
|
Result := (ADbgClass <> nil) and ADbgClass.NeedsExePath;
|
|
end;
|
|
|
|
function TInitDebuggerFrame.GetCfgDefaultExe(ADbgCfg: TDebuggerPropertiesConfig): String;
|
|
begin
|
|
Result := '';
|
|
if (ADbgCfg <> nil) then
|
|
Result := GetCfgDefaultExe(ADbgCfg.DebuggerClass);
|
|
end;
|
|
|
|
function TInitDebuggerFrame.CfgNeedsDebuggerPath(ADbgCfg: TDebuggerPropertiesConfig): boolean;
|
|
begin
|
|
Result := (ADbgCfg <> nil) and (ADbgCfg.DebuggerClass <> nil) and
|
|
ADbgCfg.DebuggerClass.NeedsExePath;
|
|
end;
|
|
|
|
function TInitDebuggerFrame.CfgHasBrokenDebuggerPath(
|
|
ADbgCfg: TDebuggerPropertiesConfig): boolean;
|
|
begin
|
|
Result := CfgNeedsDebuggerPath(ADbgCfg);
|
|
if Result then
|
|
Result := CheckDebuggerQuality(ADbgCfg.DebuggerFilename) <> sdfOk ;
|
|
end;
|
|
|
|
procedure TInitDebuggerFrame.ShowCurrentDbgClass;
|
|
begin
|
|
if FCurDbgCfg <> nil then
|
|
edDebuggerName.Caption := FCurDbgCfg.DisplayName
|
|
else
|
|
edDebuggerName.Caption := '';
|
|
cmbDebuggerName.Visible := False;
|
|
edDebuggerName.Visible := True;
|
|
GroupBox1.Caption := InitDlgDebugCurrent;
|
|
end;
|
|
|
|
procedure TInitDebuggerFrame.ShowRecommentedDbgClass;
|
|
begin
|
|
edDebuggerName.Caption := RecommendedClass.Caption;
|
|
cmbDebuggerName.Visible := False;
|
|
edDebuggerName.Visible := True;
|
|
GroupBox1.Caption := InitDlgDebugNew;
|
|
end;
|
|
|
|
procedure TInitDebuggerFrame.ShowSelectedDbgClass;
|
|
begin
|
|
cmbDebuggerName.Visible := True;
|
|
edDebuggerName.Visible := False;
|
|
GroupBox1.Caption := InitDlgDebugNew;
|
|
end;
|
|
|
|
procedure TInitDebuggerFrame.HideDebuggerPath;
|
|
begin
|
|
pnlDbgPath.Visible := False;
|
|
end;
|
|
|
|
procedure TInitDebuggerFrame.MaybeShowDebuggerPathForCurrentCfg;
|
|
begin
|
|
PnlSelectDbgPath.Visible := False;
|
|
edDebuggerPathResolved.Visible := False;
|
|
edDebuggerPath.Visible := CfgNeedsDebuggerPath(FCurDbgCfg);
|
|
pnlDbgPath.Visible := edDebuggerPath.Visible;
|
|
|
|
if not edDebuggerPath.Visible then
|
|
exit;
|
|
|
|
lbDebuggerPath.Caption := InitDlgDebugExternalExePathDisplay;
|
|
edDebuggerPath.Caption := FCurDbgCfg.DebuggerFilename;
|
|
|
|
MaybeShowDebuggerPathResolved;
|
|
end;
|
|
|
|
procedure TInitDebuggerFrame.MaybeShowDebuggerPathCombo(
|
|
ADbgCfg: TDebuggerPropertiesConfig; ADbgClass: TDebuggerIntfClass);
|
|
var
|
|
p: TStringDynArray;
|
|
DefExe, s: string;
|
|
i: Integer;
|
|
begin
|
|
if (ADbgClass = nil) and (ADbgCfg <> nil) then
|
|
ADbgClass := ADbgCfg.DebuggerClass;
|
|
|
|
edDebuggerPath.Visible := False;
|
|
edDebuggerPathResolved.Visible := False;
|
|
PnlSelectDbgPath.Visible := CfgNeedsDebuggerPath(ADbgClass);
|
|
pnlDbgPath.Visible := PnlSelectDbgPath.Visible;
|
|
|
|
if not PnlSelectDbgPath.Visible then begin
|
|
FPathDbgCfg := nil;
|
|
exit;
|
|
end;
|
|
|
|
DefExe := GetCfgDefaultExe(ADbgClass);
|
|
if DefExe = '' then
|
|
DefExe := '?';
|
|
lbDebuggerPath.Caption := Format(
|
|
InitDlgDebugExternalExePathPrompt,
|
|
[DefExe]
|
|
);
|
|
|
|
if FInPathLock = 0 then begin
|
|
if ADbgCfg = FPathDbgCfg then
|
|
cmbDebuggerPath.Items.Clear
|
|
else
|
|
cmbDebuggerPath.Clear;
|
|
if (ADbgCfg <> nil) and (ADbgCfg.DebuggerFilename <> '') then
|
|
cmbDebuggerPath.AddItem(ADbgCfg.DebuggerFilename, TObject(-1));
|
|
|
|
s := '';
|
|
if ADbgClass <> nil then
|
|
s := ADbgClass.ExePaths;
|
|
p := SplitString(
|
|
s +
|
|
';$Path($(CompPath))/'+ DefExe +
|
|
';' + DefExe,
|
|
';'
|
|
);
|
|
for i := 0 to Length(p) - 1 do begin
|
|
if (p[i] <> '') and
|
|
(cmbDebuggerPath.Items.IndexOf(p[i]) < 0) and
|
|
(CheckDebuggerQuality(p[i]) = sdfOk)
|
|
then
|
|
cmbDebuggerPath.AddItem(p[i], TObject(PtrUInt(i)));
|
|
end;
|
|
if FUserDbgPath <> '' then
|
|
cmbDebuggerPath.AddItem(FUserDbgPath, TObject(-2));
|
|
|
|
if ADbgCfg <> FPathDbgCfg then begin
|
|
if (FLastDbgPath <> '') or (ADbgCfg = nil) then
|
|
cmbDebuggerPath.Text := FLastDbgPath
|
|
else
|
|
cmbDebuggerPath.Text := ADbgCfg.DebuggerFilename;
|
|
if (ADbgCfg = nil) and (cmbDebuggerPath.Text = '') and (cmbDebuggerPath.Items.Count > 0) then
|
|
cmbDebuggerPath.ItemIndex := 0;
|
|
end;
|
|
end;
|
|
|
|
FPathDbgCfg := ADbgCfg;
|
|
MaybeShowDebuggerPathResolved;
|
|
end;
|
|
|
|
procedure TInitDebuggerFrame.MaybeShowDebuggerPathResolved;
|
|
var
|
|
s, r: String;
|
|
begin
|
|
s := GetVisibleDebuggerPath;
|
|
r := EnvironmentOptions.GetParsedValue(eopDebuggerFilename, s);
|
|
edDebuggerPathResolved.Text := r;
|
|
edDebuggerPathResolved.Visible := (r <> '') and (CompareFilenames(r, s) <> 0);
|
|
end;
|
|
|
|
function TInitDebuggerFrame.GetDebuggerClassNote(out ANote: String
|
|
): TSDFilenameQuality;
|
|
var
|
|
c: TDebuggerPropertiesConfig;
|
|
begin
|
|
Result := resOk;
|
|
ANote := '';
|
|
|
|
c := GetVisibleDebuggerCfg;
|
|
if (c = nil) and rbCreateNew.Checked then
|
|
exit; // rbCreateNew;
|
|
|
|
if (FCurrentState = cdsNotSupported) and not(rbChange.Checked or rbCreateNew.Checked) then begin
|
|
Result := resErr;
|
|
ANote := InitDlgDebugClassNoteErrorNotSupported;
|
|
exit;
|
|
end;
|
|
|
|
if (c = nil) or (c.DebuggerClass = nil) then begin
|
|
Result := resErr;
|
|
ANote := InitDlgDebugClassNoteErrorNotConfigured;
|
|
if FCurrentState = cdsNotRegistered then
|
|
ANote := ANote + LineEnding + InitDlgDebugClassNoteErrorNotConfiguredMissingPackage;
|
|
exit;
|
|
end;
|
|
|
|
if c.DebuggerClass = RecommendedClass then begin
|
|
ANote := ''; //'The backend is of the recommended type';
|
|
exit;
|
|
end;
|
|
|
|
Result := resHint;
|
|
if (FCurrentState = cdsUpdateToFpDbgNeeded) and
|
|
not(rbCreateNew.Checked or rbChange.Checked)
|
|
then
|
|
Result := resWarn;
|
|
ANote := InitDlgDebugClassNoteHintNotRecommended;
|
|
end;
|
|
|
|
function TInitDebuggerFrame.GetDebuggerPathNote(out ANote: String
|
|
): TSDFilenameQuality;
|
|
var
|
|
s: String;
|
|
begin
|
|
Result := resOk;
|
|
ANote := '';
|
|
if CfgNeedsDebuggerPath(GetVisibleDebuggerClass) then begin
|
|
s := GetVisibleDebuggerPath;
|
|
|
|
if s = '' then begin
|
|
Result := resErr;
|
|
if rbCreateNew.Checked then
|
|
ANote := InitDlgDebugPathNoteErrorNoDefaultFound
|
|
else
|
|
ANote := InitDlgDebugPathNoteErrorNoExeSpecified;
|
|
end
|
|
else begin
|
|
Result := resErr;
|
|
case CheckDebuggerQuality(s) of
|
|
sdfOk: Result := resOk;
|
|
sdfNotFound: ANote := InitDlgDebugPathNoteErrorExeNotFound;
|
|
sdfIsDirectory: ANote := InitDlgDebugPathNoteErrorExeIsDirectory;
|
|
sdfNotExecutable: ANote := InitDlgDebugPathNoteErrorExeNotRunnable;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TInitDebuggerFrame.Init;
|
|
var
|
|
r: TDebuggerIntfClass;
|
|
i: Integer;
|
|
c: TDebuggerPropertiesConfig;
|
|
begin
|
|
inc(FInChangeLock);
|
|
try
|
|
FCurrentState := CheckCurrentDebuggerSetup;
|
|
FCurDbgCfg := DebuggerOptions.CurrentDebuggerPropertiesConfig;
|
|
FPathDbgCfg := TDebuggerPropertiesConfig(-1);
|
|
|
|
r := RecommendedClass;
|
|
|
|
btnBrowse.Caption:=lisPathEditBrowse;
|
|
SpeedButton1.Images := IDEImages.Images_16;
|
|
SpeedButton1.ImageIndex := IDEImages.LoadImage('btn_help');
|
|
|
|
lbAboutDebugger.Caption := Format(
|
|
InitDlgDebugHeaderDefaultForYourOSArchIsS,
|
|
[ r.Caption ]
|
|
);
|
|
|
|
if FCurDbgCfg <> nil then begin
|
|
edDebuggerName.Caption := FCurDbgCfg.DisplayName;
|
|
edDebuggerPath.Caption := FCurDbgCfg.DebuggerFilename;
|
|
end
|
|
else begin
|
|
edDebuggerName.Caption := '';
|
|
edDebuggerPath.Caption := '';
|
|
end;
|
|
|
|
FSelDbgCfg := nil;
|
|
if DebuggerOptions.DebuggerPropertiesConfigList.Count > 0 then begin
|
|
for i := 0 to DebuggerOptions.DebuggerPropertiesConfigList.Count - 1 do begin
|
|
c := DebuggerOptions.DebuggerPropertiesConfigList.Opt[i];
|
|
cmbDebuggerName.AddItem(c.DisplayName, c);
|
|
end;
|
|
i := 0;
|
|
if FCurDbgCfg <> nil then
|
|
i := cmbDebuggerName.Items.IndexOfObject(FCurDbgCfg);
|
|
cmbDebuggerName.ItemIndex := i;
|
|
FSelDbgCfg := TDebuggerPropertiesConfig(cmbDebuggerName.Items.Objects[i]);
|
|
end;
|
|
|
|
rbKeep.Caption := InitDlgDebugKeepBackend;
|
|
rbChangePath.Caption := InitDlgDebugChangePath;
|
|
rbCreateNew.Caption := InitDlgDebugCreateANewRecommendedBack;
|
|
rbChange.Caption := InitDlgDebugSelectAnExistingBackend;
|
|
rbIgnore.Caption := InitDlgDebugIgnore;
|
|
|
|
case FCurrentState of
|
|
cdsOk: begin
|
|
rbKeep.Visible := True;
|
|
rbChangePath.Visible := CfgNeedsDebuggerPath(FCurDbgCfg);
|
|
rbCreateNew.Visible := FCurDbgCfg.DebuggerClass <> RecommendedClass;
|
|
rbChange.Visible := DebuggerOptions.DebuggerPropertiesConfigList.Count > 1;
|
|
rbIgnore.Visible := False;
|
|
|
|
rbKeep.Checked := True;
|
|
end;
|
|
//cdsNoActive: begin
|
|
// end;
|
|
//cdsNotRegistered: begin
|
|
// end;
|
|
//cdsNotSupported: begin
|
|
// end;
|
|
cdsUpdateToFpDbgNeeded: begin
|
|
rbKeep.Visible := True;
|
|
rbChangePath.Visible := False;
|
|
rbCreateNew.Visible := True;
|
|
rbChange.Visible := DebuggerOptions.DebuggerPropertiesConfigList.Count >= 1;
|
|
rbIgnore.Visible := False;
|
|
|
|
rbKeep.Checked := True;
|
|
end;
|
|
else begin
|
|
rbKeep.Visible := False;
|
|
rbChangePath.Visible := False;
|
|
rbCreateNew.Visible := True;
|
|
rbChange.Visible := DebuggerOptions.DebuggerPropertiesConfigList.Count >= 1;
|
|
rbIgnore.Visible := True;
|
|
|
|
//rbIgnore.Checked := True;
|
|
end;
|
|
end;
|
|
finally
|
|
dec(FInChangeLock);
|
|
end;
|
|
end;
|
|
|
|
function TInitDebuggerFrame.UpdateState: TSDFilenameQuality;
|
|
var
|
|
s, ClassNote, PathNote: String;
|
|
PathRes: TSDFilenameQuality;
|
|
HasUnregistered, HasRebuildNote: Boolean;
|
|
h: Integer;
|
|
begin
|
|
inc(FInChangeLock);
|
|
try
|
|
DisableAutoSizing;
|
|
Result := resOk;
|
|
|
|
// This only needs update, if a macro in the path changes
|
|
if FCurrentState = cdsOk then begin
|
|
if CfgHasBrokenDebuggerPath(FCurDbgCfg) then begin
|
|
rbKeep.Visible := False;
|
|
rbIgnore.Visible := True;
|
|
rbKeep.Checked := False;
|
|
end
|
|
else begin
|
|
rbKeep.Visible := True;
|
|
rbIgnore.Visible := False;
|
|
if rbIgnore.Checked then rbKeep.Checked := True;
|
|
end;
|
|
end;
|
|
|
|
if rbCreateNew.Checked then begin
|
|
ShowRecommentedDbgClass;
|
|
MaybeShowDebuggerPathCombo(nil, RecommendedClass);
|
|
end
|
|
else
|
|
if rbChangePath.Checked then begin
|
|
ShowCurrentDbgClass;
|
|
MaybeShowDebuggerPathCombo(FCurDbgCfg);
|
|
end
|
|
else
|
|
if rbChange.Checked then begin
|
|
ShowSelectedDbgClass;
|
|
MaybeShowDebuggerPathCombo(FSelDbgCfg);
|
|
end
|
|
else
|
|
begin // rbKeep or rbIgnore
|
|
ShowCurrentDbgClass;
|
|
MaybeShowDebuggerPathForCurrentCfg;
|
|
end;
|
|
|
|
|
|
s := '';
|
|
h := 0;
|
|
HasUnregistered := DebuggerOptions.DebuggerPropertiesConfigList.Unloaded.Count > 0;
|
|
Result := GetDebuggerClassNote(ClassNote);
|
|
PathRes := GetDebuggerPathNote(PathNote);
|
|
HasRebuildNote := False;
|
|
|
|
if (FCurrentState in [cdsNotRegistered, cdsNoActive]) and HasUnregistered then begin
|
|
HasRebuildNote := True;
|
|
s := s + InitDlgDebugStateMissingPackages + LineEnding;
|
|
h := h + 50;
|
|
end
|
|
else
|
|
if (FCurrentState = cdsUpdateToFpDbgNeeded) then begin
|
|
s := s + InitDlgDebugStateUpdateBackend + LineEnding;
|
|
h := h + 40;
|
|
//Result := MaxResult(resHint, Result);
|
|
end;
|
|
|
|
if rbChange.Visible and rbCreateNew.Visible and
|
|
( (FCurrentState <> cdsOk) or
|
|
((FCurDbgCfg <> nil) and (FCurDbgCfg.DebuggerClass <> RecommendedClass))
|
|
)
|
|
then begin
|
|
if (CountRecommendedBackend = 0) and rbChange.Checked then begin
|
|
s := s + InitDlgDebugStateRecommendedNotInList + LineEnding;
|
|
h := h + 25;
|
|
end
|
|
else
|
|
if (CountRecommendedBackend > 0) and rbCreateNew.Checked then begin
|
|
s := s + InitDlgDebugStateRecommendedFoundInList + LineEnding;
|
|
h := h + 25;
|
|
end
|
|
end;
|
|
|
|
if (s <> '') and not ( (Result in [resOk, resHint]) and (PathRes in [resOk, resHint]) ) then
|
|
s := s + LineEnding;
|
|
|
|
if (ClassNote <> '') and not (Result in [resOk, resHint]) then begin
|
|
s := s + ClassNote + LineEnding;
|
|
ClassNote := '';
|
|
end;
|
|
|
|
if (PathNote <> '') and not (PathRes in [resOk, resHint]) then begin
|
|
s := s + PathNote + LineEnding;
|
|
PathNote := '';
|
|
Result := MaxResult(PathRes, Result);
|
|
end;
|
|
|
|
if Result in [resOk, resHint] then begin
|
|
if s <> '' then s := s + LineEnding;
|
|
s := s + InitDlgDebugStateSetupOk + LineEnding;
|
|
end;
|
|
|
|
if (ClassNote <> '') then
|
|
s := s + ClassNote + LineEnding;
|
|
if (PathNote <> '') then
|
|
s := s + PathNote + LineEnding;
|
|
|
|
if HasRebuildNote then begin
|
|
s := s + LineEnding + Format(InitDlgDebugStateMissingPackageRebuild, [''+LineEnding]);
|
|
h := h + 40;
|
|
end
|
|
else
|
|
if HasUnregistered then begin
|
|
s := s + LineEnding + InitDlgDebugStateMissingPackageFooter;
|
|
h := h + 70;
|
|
end;
|
|
|
|
if rbIgnore.Checked and (Result = resErr) and
|
|
(FCurrentState in [cdsNoActive, cdsNotRegistered])
|
|
then
|
|
Result := resWarn;
|
|
|
|
edDebuggerNotes.Height := ClientHeight - edDebuggerNotes.Top - 5;
|
|
edDebuggerNotes.Constraints.MinHeight := NOTES_MIN_HEIGHT + h;
|
|
edDebuggerNotes.Text := s;
|
|
|
|
finally
|
|
dec(FInChangeLock);
|
|
|
|
EnableAutoSizing;
|
|
FrameResize(nil);
|
|
end;
|
|
end;
|
|
|
|
procedure TInitDebuggerFrame.ApplySelection;
|
|
var
|
|
c: TDebuggerPropertiesConfig;
|
|
n: String;
|
|
i: Integer;
|
|
begin
|
|
if rbChangePath.Checked then begin
|
|
assert(DebuggerOptions.CurrentDebuggerPropertiesConfig<>nil, 'TInitDebuggerFrame.ApplySelection: DebuggerOptions.CurrentDebuggerPropertiesConfig<>nil');
|
|
if DebuggerOptions.CurrentDebuggerPropertiesConfig <> nil then
|
|
DebuggerOptions.CurrentDebuggerPropertiesConfig.DebuggerFilename := GetVisibleDebuggerPath;
|
|
DebuggerOptions.SaveDebuggerPropertiesList; // Update XML
|
|
end
|
|
else
|
|
if rbChange.Checked then begin
|
|
assert(FSelDbgCfg <> nil, 'TInitDebuggerFrame.ApplySelection: FSelDbgCfg <> nil');
|
|
if FSelDbgCfg <> nil then begin
|
|
FSelDbgCfg.DebuggerFilename:=GetVisibleDebuggerPath;
|
|
DebuggerOptions.CurrentDebuggerPropertiesConfig := FSelDbgCfg;
|
|
end;
|
|
DebuggerOptions.SaveDebuggerPropertiesList; // Update XML
|
|
end
|
|
else
|
|
if rbCreateNew.Checked then begin
|
|
c := TDebuggerPropertiesConfig.CreateForDebuggerClass(RecommendedClass, True);
|
|
n := 'Default';
|
|
i := 0;
|
|
if DebuggerOptions.DebuggerPropertiesConfigList.EntryByName(n, c.ConfigClass) <> nil then
|
|
while (i <= DebuggerOptions.DebuggerPropertiesConfigList.Count) and
|
|
(DebuggerOptions.DebuggerPropertiesConfigList.EntryByName(n+' '+IntToStr(i), c.ConfigClass) <> nil)
|
|
do
|
|
inc(i);
|
|
if i > 0 then
|
|
n := n + ' ' + IntToStr(i);
|
|
c.ConfigName := n;
|
|
DebuggerOptions.CurrentDebuggerPropertiesConfig := c;
|
|
if CfgNeedsDebuggerPath(c) then
|
|
c.DebuggerFilename := GetVisibleDebuggerPath;
|
|
DebuggerOptions.SaveDebuggerPropertiesList; // Update XML
|
|
end;
|
|
|
|
// else
|
|
//if FCurrentState = cdsUpdateToFpDbgNeeded then begin
|
|
//end;
|
|
// caller will save config, and increase version
|
|
end;
|
|
|
|
end.
|
|
|