IdeDebugger: add ValueFormatter to watch properties

This commit is contained in:
Martin 2024-04-10 21:18:37 +02:00
parent b7d9762602
commit 442dfce7a8
8 changed files with 839 additions and 87 deletions

View File

@ -113,6 +113,7 @@ type
defFunctionCallRunAllThreads, //
defExtraDepth, // Evaluate 1 extra level of sub-elements => i.e., evaluate each nested sub-item
defSkipValConv,
defSkipValueFormatter, // Don't use any Valueformatter // not eval related
defMemDump, // Return Memory Dump, **instead** of value
// deprecated
defNoTypeInfo, // No Typeinfo object will be returned // for structures that means a printed value will be returned

View File

@ -6836,6 +6836,7 @@ begin
Result.Enabled := Enabled;
Result.DisplayFormat := DisplayFormat;
Result.DbgBackendConverter := DbgBackendConverter;
Result.DbgValueFormatter := DbgValueFormatter;
Result.FDisplayName := ADispName;
if (defClassAutoCast in EvaluateFlags) then
Result.EvaluateFlags := Result.EvaluateFlags + [defClassAutoCast];
@ -6933,7 +6934,6 @@ begin
if AConfig.GetValue(APath + 'SkipFpDbgConv', False)
then Include(FEvaluateFlags, defSkipValConv)
else Exclude(FEvaluateFlags, defSkipValConv);
s := AConfig.GetValue(APath + 'FpDbgConv', '');
if s <> '' then begin
if AConfig.GetValue(APath + 'FpDbgConvIsFromProject', False) then
@ -6942,6 +6942,17 @@ begin
DbgBackendConverter := DebuggerOptions.BackendConverterConfig.ItemByName(s);
end;
if AConfig.GetValue(APath + 'SkipValueFormatter', False)
then Include(FEvaluateFlags, defSkipValueFormatter)
else Exclude(FEvaluateFlags, defSkipValueFormatter);
s := AConfig.GetValue(APath + 'ValueFormatter', '');
if s <> '' then begin
if AConfig.GetValue(APath + 'ValueFormatterIsFromProject', False) then
DbgValueFormatter := DbgProjectLink.ValueFormatterConfig.ItemByName(s)
else
DbgValueFormatter := DebuggerOptions.ValueFormatterConfig.ItemByName(s);
end;
TIdeWatchValueList(FValueList).LoadDataFromXMLConfig(AConfig, APath + 'ValueList/');
end;
@ -6965,6 +6976,22 @@ begin
AConfig.SetDeleteValue(APath + 'FpDbgConvIsFromProject',
(DbgProjectLink.BackendConverterConfig.IndexOf(DbgBackendConverter) >= 0),
False);
end
else begin
AConfig.SetDeleteValue(APath + 'FpDbgConv', '', '');
AConfig.SetDeleteValue(APath + 'FpDbgConvIsFromProject', False, False);
end;
AConfig.SetDeleteValue(APath + 'SkipValueFormatter', defSkipValueFormatter in FEvaluateFlags, False);
if DbgValueFormatter <> nil then begin
AConfig.SetDeleteValue(APath + 'ValueFormatter', DbgValueFormatter.Name, '');
AConfig.SetDeleteValue(APath + 'ValueFormatterIsFromProject',
(DbgProjectLink.ValueFormatterConfig.IndexOf(DbgValueFormatter) >= 0),
False);
end
else begin
AConfig.SetDeleteValue(APath + 'ValueFormatter', '', '');
AConfig.SetDeleteValue(APath + 'ValueFormatterIsFromProject', False, False);
end;
TIdeWatchValueList(FValueList).SaveDataToXMLConfig(AConfig, APath + 'ValueList/');
@ -7094,7 +7121,6 @@ begin
if AConfig.GetValue(APath + 'SkipFpDbgConv', False)
then Include(FEvaluateFlags, defSkipValConv)
else Exclude(FEvaluateFlags, defSkipValConv);
s := AConfig.GetValue(APath + 'FpDbgConv', '');
if s <> '' then begin
if AConfig.GetValue(APath + 'FpDbgConvIsFromProject', False) then
@ -7102,6 +7128,17 @@ begin
else
DbgBackendConverter := DebuggerOptions.BackendConverterConfig.ItemByName(s);
end;
if AConfig.GetValue(APath + 'SkipValueFormatter', False)
then Include(FEvaluateFlags, defSkipValueFormatter)
else Exclude(FEvaluateFlags, defSkipValueFormatter);
s := AConfig.GetValue(APath + 'ValueFormatter', '');
if s <> '' then begin
if AConfig.GetValue(APath + 'ValueFormatterIsFromProject', False) then
DbgValueFormatter := DbgProjectLink.ValueFormatterConfig.ItemByName(s)
else
DbgValueFormatter := DebuggerOptions.ValueFormatterConfig.ItemByName(s);
end;
end;
procedure TCurrentWatch.SaveToXMLConfig(const AConfig: TXMLConfig; const APath: string);
@ -7122,6 +7159,22 @@ begin
AConfig.SetDeleteValue(APath + 'FpDbgConvIsFromProject',
(DbgProjectLink.BackendConverterConfig.IndexOf(DbgBackendConverter) >= 0),
False);
end
else begin
AConfig.SetDeleteValue(APath + 'FpDbgConv', '', '');
AConfig.SetDeleteValue(APath + 'FpDbgConvIsFromProject', False, False);
end;
AConfig.SetDeleteValue(APath + 'SkipValueFormatter', defSkipValueFormatter in FEvaluateFlags, False);
if DbgValueFormatter <> nil then begin
AConfig.SetDeleteValue(APath + 'ValueFormatter', DbgValueFormatter.Name, '');
AConfig.SetDeleteValue(APath + 'ValueFormatterIsFromProject',
(DbgProjectLink.ValueFormatterConfig.IndexOf(DbgValueFormatter) >= 0),
False);
end
else begin
AConfig.SetDeleteValue(APath + 'ValueFormatter', '', '');
AConfig.SetDeleteValue(APath + 'ValueFormatterIsFromProject', False, False);
end;
end;

View File

@ -154,11 +154,14 @@ type
TWatch = class(TDelayedUdateItem)
private
FDbgValueFormatter: TIdeDbgValueFormatterSelector;
FFreeNotificationList: TMethodList;
FFirstIndexOffs: Int64;
FDbgBackendConverter: TIdeDbgValueConvertSelector;
procedure DoDbgValueFormatterFreed(Sender: TObject);
procedure FDbgBackendConverterFreed(Sender: TObject);
procedure SetDbgValueFormatter(AValue: TIdeDbgValueFormatterSelector);
procedure SetDisplayFormat(AValue: TWatchDisplayFormat);
procedure SetEnabled(AValue: Boolean);
procedure SetEvaluateFlags(AValue: TWatcheEvaluateFlags);
@ -201,6 +204,7 @@ type
property FirstIndexOffs: Int64 read FFirstIndexOffs write SetFirstIndexOffs;
property RepeatCount: Integer read FRepeatCount write SetRepeatCount;
property DbgBackendConverter: TIdeDbgValueConvertSelector read FDbgBackendConverter write SetDbgBackendConverter;
property DbgValueFormatter: TIdeDbgValueFormatterSelector read FDbgValueFormatter write SetDbgValueFormatter;
property Values[const AThreadId: Integer; const AStackFrame: Integer]: TWatchValue
read GetValue;
property ValueList: TWatchValueList read FValueList;
@ -656,6 +660,27 @@ begin
DoModified;
end;
procedure TWatch.DoDbgValueFormatterFreed(Sender: TObject);
begin
FDbgValueFormatter := nil;
DoDisplayFormatChanged;
end;
procedure TWatch.SetDbgValueFormatter(AValue: TIdeDbgValueFormatterSelector);
begin
if FDbgValueFormatter = AValue then Exit;
if FDbgValueFormatter <> nil then
FDbgValueFormatter.RemoveFreeNotification(@DoDbgValueFormatterFreed);
FDbgValueFormatter := AValue;
if FDbgValueFormatter <> nil then
FDbgValueFormatter.AddFreeNotification(@DoDbgValueFormatterFreed);
DoDisplayFormatChanged;
end;
function TWatch.GetDisplayFormat: TWatchDisplayFormat;
begin
Result := FDisplayFormat;
@ -760,6 +785,7 @@ begin
TWatch(Dest).FRepeatCount := FRepeatCount;
TWatch(Dest).FEvaluateFlags := FEvaluateFlags;
TWatch(Dest).DbgBackendConverter := DbgBackendConverter;
TWatch(Dest).DbgValueFormatter := DbgValueFormatter;
TWatch(Dest).FValueList.Assign(FValueList);
end
else inherited;
@ -820,6 +846,8 @@ destructor TWatch.Destroy;
begin
if FDbgBackendConverter <> nil then
FDbgBackendConverter.RemoveFreeNotification(@FDbgBackendConverterFreed);
if FDbgValueFormatter <> nil then
FDbgValueFormatter.RemoveFreeNotification(@DoDbgValueFormatterFreed);
FValueList.Clear;

View File

@ -6,7 +6,7 @@ interface
uses
Classes, SysUtils, fgl, StrUtils,
Laz2_XMLCfg,
Laz2_XMLCfg, LazClasses,
// LazDebuggerIntf
LazDebuggerIntf, DbgUtilsTypePatternList,
// DebuggerIntf
@ -21,7 +21,7 @@ type
{ TIdeDbgValueFormatterSelector }
TIdeDbgValueFormatterSelector = class
TIdeDbgValueFormatterSelector = class(TFreeNotifyingObject)
private
FOriginalValue: TLazDbgIdeValFormatterOriginalValue;
FValFormatter: ILazDbgIdeValueFormatterIntf;
@ -45,6 +45,11 @@ type
procedure LoadDataFromXMLConfig(const AConfig: TRttiXMLConfig; const APath: string);
procedure SaveDataToXMLConfig(const AConfig: TRttiXMLConfig; const APath: string);
function MatchesAll(AWatchValue: IWatchResultDataIntf; ADisplayFormat: TWatchDisplayFormat): Boolean;
function FormatValue(AWatchValue: IWatchResultDataIntf; ADisplayFormat: TWatchDisplayFormat;
AWatchResultPrinter: IWatchResultPrinter; out APrintedValue: String
): Boolean;
function IsMatchingTypeName(ATypeName: String): boolean;
function IsMatchingInheritedTypeName(ATypeName: String): boolean;
property FilterDisplayFormats: TValueDisplayFormats read FFilterDisplayFormats write SetFilterDisplayFormats;
@ -78,6 +83,8 @@ type
procedure LoadDataFromXMLConfig(const AConfig: TRttiXMLConfig; const APath: string);
procedure SaveDataToXMLConfig(const AConfig: TRttiXMLConfig; const APath: string);
function ItemByName(AName: String): TIdeDbgValueFormatterSelector;
property Changed: Boolean read FChanged write SetChanged;
property OnChanged: TNotifyEvent read FOnChanged write FOnChanged;
public
@ -212,6 +219,70 @@ begin
Def.Free;
end;
function TIdeDbgValueFormatterSelector.MatchesAll(AWatchValue: IWatchResultDataIntf;
ADisplayFormat: TWatchDisplayFormat): Boolean;
var
j: Integer;
a: IWatchResultDataIntf;
begin
Result := False;
if (ValFormatter = nil) or
(not (vffFormatValue in ValFormatter.SupportedFeatures))
or
( ADisplayFormat.MemDump and (
( not(vffValueMemDump in ValFormatter.SupportedFeatures) ) or
( (vdfgCategory in ValFormatter.SupportedDisplayFormatFilters) and (not (vdfCategoryMemDump in FFilterDisplayFormats)) )
) )
or
( (not ADisplayFormat.MemDump) and (
( not(vffValueData in ValFormatter.SupportedFeatures) ) or
( (vdfgCategory in ValFormatter.SupportedDisplayFormatFilters) and (not (vdfCategoryData in FFilterDisplayFormats)) ) or
// TOOD: 2nd num
( (vdfgBase in ValFormatter.SupportedDisplayFormatFilters) and (not (ADisplayFormat.Num.BaseFormat in FFilterDisplayFormats)) ) or
( (vdfgSign in ValFormatter.SupportedDisplayFormatFilters) and (not (ADisplayFormat.Num.SignFormat in FFilterDisplayFormats)) ) or
( (vdfgEnum in ValFormatter.SupportedDisplayFormatFilters) and (not (ADisplayFormat.Enum.MainFormat in FFilterDisplayFormats)) ) or
( (vdfgBool in ValFormatter.SupportedDisplayFormatFilters) and (not (ADisplayFormat.Bool.MainFormat in FFilterDisplayFormats)) ) or
( (vdfgChar in ValFormatter.SupportedDisplayFormatFilters) and (not (ADisplayFormat.Char.MainFormat in FFilterDisplayFormats)) ) or
( (vdfgFloat in ValFormatter.SupportedDisplayFormatFilters) and (not (ADisplayFormat.Float.NumFormat in FFilterDisplayFormats)) ) or
( (vdfgStruct in ValFormatter.SupportedDisplayFormatFilters) and (not (ADisplayFormat.Struct.DataFormat in FFilterDisplayFormats)) ) or
( (vdfgStructAddress in ValFormatter.SupportedDisplayFormatFilters) and (not (ADisplayFormat.Struct.ShowPointerFormat in FFilterDisplayFormats)) ) or
( (vdfgAddress in ValFormatter.SupportedDisplayFormatFilters) and (not (ADisplayFormat.Pointer.Address.TypeFormat in FFilterDisplayFormats)) ) or
( (vdfgPointerDeref in ValFormatter.SupportedDisplayFormatFilters) and (not (ADisplayFormat.Pointer.DerefFormat in FFilterDisplayFormats)) )
) )
then
exit;
//AWatchValue.ValueKind;
if not IsMatchingTypeName(AWatchValue.TypeName) then begin
if not MatchInherited then
exit;
j := AWatchValue.AnchestorCount - 1;
while (j >= 0) do begin
a := AWatchValue.Anchestors[j];
if (a <> nil) and IsMatchingInheritedTypeName(a.TypeName) then
break;
dec(j);
end;
if j < 0 then
exit;
end;
Result := True;
end;
function TIdeDbgValueFormatterSelector.FormatValue(AWatchValue: IWatchResultDataIntf;
ADisplayFormat: TWatchDisplayFormat; AWatchResultPrinter: IWatchResultPrinter; out
APrintedValue: String): Boolean;
begin
Result := ValFormatter.FormatValue(AWatchValue, ADisplayFormat, AWatchResultPrinter, APrintedValue);
if Result then begin
case OriginalValue of
vfovAtEnd: APrintedValue := APrintedValue + ' = ' + AWatchResultPrinter.PrintWatchValue(AWatchValue, ADisplayFormat);
vfovAtFront: APrintedValue := AWatchResultPrinter.PrintWatchValue(AWatchValue, ADisplayFormat) + ' = ' + APrintedValue;
end;
end;
end;
function TIdeDbgValueFormatterSelector.IsMatchingTypeName(ATypeName: String): boolean;
begin
Result := FMatchTypeNames.CheckTypeName(ATypeName);
@ -306,6 +377,18 @@ begin
Def.Free;
end;
function TIdeDbgValueFormatterSelectorList.ItemByName(AName: String): TIdeDbgValueFormatterSelector;
var
i: Integer;
begin
Result := nil;
i := Count - 1;
while (i >= 0) and (Items[i].Name <> AName) do
dec(i);
if i >= 0 then
Result := Items[i];
end;
destructor TIdeDbgValueFormatterSelectorList.Destroy;
begin
FreeChangeNotifications;
@ -316,61 +399,17 @@ function TIdeDbgValueFormatterSelectorList.FormatValue(
AWatchValue: IWatchResultDataIntf; ADisplayFormat: TWatchDisplayFormat;
AWatchResultPrinter: IWatchResultPrinter; out APrintedValue: String): Boolean;
var
i, j: Integer;
a: IWatchResultDataIntf;
i: Integer;
f: TIdeDbgValueFormatterSelector;
v: ILazDbgIdeValueFormatterIntf;
begin
for i := 0 to Count - 1 do begin
f := Items[i];
v := f.ValFormatter;
if (not (vffFormatValue in v.SupportedFeatures))
or (v = nil)
or
( ADisplayFormat.MemDump and (
( not(vffValueMemDump in v.SupportedFeatures) ) or
( (vdfgCategory in v.SupportedDisplayFormatFilters) and (not (vdfCategoryMemDump in f.FFilterDisplayFormats)) )
) )
or
( (not ADisplayFormat.MemDump) and (
( not(vffValueData in v.SupportedFeatures) ) or
( (vdfgCategory in v.SupportedDisplayFormatFilters) and (not (vdfCategoryData in f.FFilterDisplayFormats)) ) or
// TOOD: 2nd num
( (vdfgBase in v.SupportedDisplayFormatFilters) and (not (ADisplayFormat.Num.BaseFormat in f.FFilterDisplayFormats)) ) or
( (vdfgSign in v.SupportedDisplayFormatFilters) and (not (ADisplayFormat.Num.SignFormat in f.FFilterDisplayFormats)) ) or
( (vdfgEnum in v.SupportedDisplayFormatFilters) and (not (ADisplayFormat.Enum.MainFormat in f.FFilterDisplayFormats)) ) or
( (vdfgBool in v.SupportedDisplayFormatFilters) and (not (ADisplayFormat.Bool.MainFormat in f.FFilterDisplayFormats)) ) or
( (vdfgChar in v.SupportedDisplayFormatFilters) and (not (ADisplayFormat.Char.MainFormat in f.FFilterDisplayFormats)) ) or
( (vdfgFloat in v.SupportedDisplayFormatFilters) and (not (ADisplayFormat.Float.NumFormat in f.FFilterDisplayFormats)) ) or
( (vdfgStruct in v.SupportedDisplayFormatFilters) and (not (ADisplayFormat.Struct.DataFormat in f.FFilterDisplayFormats)) ) or
( (vdfgStructAddress in v.SupportedDisplayFormatFilters) and (not (ADisplayFormat.Struct.ShowPointerFormat in f.FFilterDisplayFormats)) ) or
( (vdfgAddress in v.SupportedDisplayFormatFilters) and (not (ADisplayFormat.Pointer.Address.TypeFormat in f.FFilterDisplayFormats)) ) or
( (vdfgPointerDeref in v.SupportedDisplayFormatFilters) and (not (ADisplayFormat.Pointer.DerefFormat in f.FFilterDisplayFormats)) )
) )
then
if not f.MatchesAll(AWatchValue, ADisplayFormat) then
continue;
if not f.IsMatchingTypeName(AWatchValue.TypeName) then begin
if not f.MatchInherited then
continue;
j := AWatchValue.AnchestorCount - 1;
while (j >= 0) do begin
a := AWatchValue.Anchestors[j];
if (a <> nil) and f.IsMatchingInheritedTypeName(a.TypeName) then
break;
dec(j);
end;
if j < 0 then
Continue;
end;
Result := f.ValFormatter.FormatValue(AWatchValue, ADisplayFormat, AWatchResultPrinter, APrintedValue);
if Result then begin
case f.OriginalValue of
vfovAtEnd: APrintedValue := APrintedValue + ' = ' + AWatchResultPrinter.PrintWatchValue(AWatchValue, ADisplayFormat);
vfovAtFront: APrintedValue := AWatchResultPrinter.PrintWatchValue(AWatchValue, ADisplayFormat) + ' = ' + APrintedValue;
end;
Result := f.FormatValue(AWatchValue, ADisplayFormat, AWatchResultPrinter, APrintedValue);
if Result then
exit;
end;
end;
Result := False;
end;

View File

@ -7,8 +7,8 @@ interface
uses
Classes, SysUtils, Math, IdeDebuggerWatchResult, IdeDebuggerUtils, IdeDebuggerDisplayFormats,
IdeDebuggerBase, IdeDebuggerStringConstants, LazDebuggerIntf, LazUTF8, IdeDebuggerWatchValueIntf,
StrUtils;
IdeDebuggerBase, IdeDebuggerStringConstants, IdeDebuggerValueFormatter, LazDebuggerIntf, LazUTF8,
IdeDebuggerWatchValueIntf, StrUtils;
type
@ -59,7 +59,8 @@ type
rpfIndent, // use Indent. Only when MultiLine
rpfMultiLine,
rpfClearMultiLine, // clean up pre-printed data
rpfPrefixOuterArrayLen
rpfPrefixOuterArrayLen,
rpfSkipValueFormatter
);
TWatchResultPrinterFormatFlags = set of TWatchResultPrinterFormatFlag;
@ -69,6 +70,7 @@ type
private
FFormatFlags: TWatchResultPrinterFormatFlags;
FLineSeparator: String;
FOnlyValueFormatter: TIdeDbgValueFormatterSelector;
FTargetAddressSize: integer;
FDisplayFormatResolver: TDisplayFormatResolver;
FInValueFormatter: Boolean;
@ -93,6 +95,8 @@ type
function PrintWatchValue(AResValue: IWatchResultDataIntf; const ADispFormat: TWatchDisplayFormat): String;
property FormatFlags: TWatchResultPrinterFormatFlags read FFormatFlags write FFormatFlags;
property OnlyValueFormatter: TIdeDbgValueFormatterSelector read FOnlyValueFormatter write FOnlyValueFormatter;
property TargetAddressSize: integer read FTargetAddressSize write FTargetAddressSize;
property DisplayFormatResolver: TDisplayFormatResolver read FDisplayFormatResolver;
end;
@ -853,9 +857,14 @@ begin
if AResValue = nil then
exit('???');
if not FInValueFormatter then begin
if not (FInValueFormatter or (rpfSkipValueFormatter in FFormatFlags)) then begin
FInValueFormatter := True;
try
if OnlyValueFormatter <> nil then begin
if OnlyValueFormatter.FormatValue(AResValue, ADispFormat, Self, Result) then
exit;
end
else
if GlobalValueFormatterSelectorList.FormatValue(AResValue, ADispFormat, Self, Result) then
exit;
finally
@ -882,7 +891,7 @@ begin
rdkUnsignedNumVal: begin
Resolved := DisplayFormatResolver.ResolveDispFormat(ADispFormat, AResValue);
Result := PrintNumber(AResValue.AsQWord, AResValue.AsInt64, AResValue.ByteSize, Resolved.Num1);
if Resolved.Num2.Visible then begin;
if Resolved.Num2.Visible then begin
Result := Result +' = ' +
PrintNumber(AResValue.AsQWord, AResValue.AsInt64, AResValue.ByteSize, Resolved.Num2);
end;

View File

@ -1205,6 +1205,9 @@ begin
if (d.ResultData <> nil) and
not( (d.ResultData.ValueKind = rdkPrePrinted) and (t <> nil) )
then begin
if defSkipValueFormatter in Watch.EvaluateFlags then
FWatchPrinter.FormatFlags := [rpfIndent, rpfMultiLine, rpfSkipValueFormatter];
FWatchPrinter.OnlyValueFormatter := Watch.DbgValueFormatter;
s := FWatchPrinter.PrintWatchValue(d.ResultData, Watch.DisplayFormat);
InspectMemo.WordWrap := True;
InspectMemo.Text := s;
@ -1502,6 +1505,10 @@ begin
if (ResData <> nil) and
not( (ResData.ValueKind = rdkPrePrinted) and (AWatchAbleResult.TypeInfo <> nil) )
then begin
if defSkipValueFormatter in TheWatch.EvaluateFlags then
FWatchDlg.FWatchPrinter.FormatFlags := [rpfIndent, rpfMultiLine, rpfSkipValueFormatter];
FWatchDlg.FWatchPrinter.OnlyValueFormatter := TheWatch.DbgValueFormatter;
Result := FWatchDlg.FWatchPrinter.PrintWatchValue(ResData, DispFormat);
end
else begin
@ -1558,7 +1565,11 @@ begin
if (ResData <> nil) and
not( (ResData.ValueKind = rdkPrePrinted) and (AWatchAbleResult.TypeInfo <> nil) )
then begin
FWatchDlg.FWatchPrinter.FormatFlags := [rpfClearMultiLine, rpfPrefixOuterArrayLen];
if defSkipValueFormatter in TheWatch.EvaluateFlags then
FWatchDlg.FWatchPrinter.FormatFlags := [rpfClearMultiLine, rpfPrefixOuterArrayLen, rpfSkipValueFormatter]
else
FWatchDlg.FWatchPrinter.FormatFlags := [rpfClearMultiLine, rpfPrefixOuterArrayLen];
FWatchDlg.FWatchPrinter.OnlyValueFormatter := TheWatch.DbgValueFormatter;
WatchValueStr := FWatchDlg.FWatchPrinter.PrintWatchValue(ResData, DispFormat);
TreeView.NodeText[AVNode, COL_WATCH_VALUE-1] := WatchValueStr;

View File

@ -172,69 +172,106 @@ object WatchPropertyDlg: TWatchPropertyDlg
AnchorSideRight.Control = Spacer2
AnchorSideRight.Side = asrBottom
Left = 287
Height = 62
Height = 84
Top = 0
Width = 281
Anchors = [akTop, akLeft, akRight]
AutoSize = True
BevelOuter = bvNone
ChildSizing.HorizontalSpacing = 3
ChildSizing.EnlargeHorizontal = crsScaleChilds
ChildSizing.ShrinkHorizontal = crsScaleChilds
ChildSizing.VerticalSpacing = 5
ChildSizing.Layout = cclLeftToRightThenTopToBottom
ChildSizing.ControlsPerLine = 2
ClientHeight = 62
ChildSizing.ControlsPerLine = 1
ClientHeight = 84
ClientWidth = 281
TabOrder = 4
object lblRepCount: TLabel
AnchorSideTop.Side = asrCenter
Left = 0
Height = 15
Top = 9
Width = 92
Height = 23
Top = 5
Width = 80
BorderSpacing.Top = 5
BorderSpacing.CellAlignVertical = ccaCenter
Caption = 'Repeat Count:'
Constraints.MinHeight = 23
Layout = tlCenter
ParentColor = False
end
object txtRepCount: TEdit
AnchorSideLeft.Control = lblRepCount
AnchorSideLeft.Side = asrBottom
AnchorSideTop.Control = lblRepCount
AnchorSideTop.Side = asrCenter
AnchorSideRight.Control = Panel2
AnchorSideRight.Side = asrBottom
Left = 98
Left = 85
Height = 23
Top = 5
Width = 183
Width = 196
Alignment = taRightJustify
BorderSpacing.Left = 6
BorderSpacing.Top = 5
Anchors = [akTop, akLeft, akRight]
BorderSpacing.Left = 5
TabOrder = 0
Text = '0'
end
object lblFpDbgConv: TLabel
AnchorSideTop.Side = asrCenter
Left = 0
Height = 15
Top = 37
Width = 92
BorderSpacing.CellAlignVertical = ccaCenter
Caption = 'lblFpDbgConv'
end
object dropFpDbgConv: TComboBox
AnchorSideLeft.Side = asrBottom
AnchorSideTop.Side = asrBottom
AnchorSideRight.Side = asrBottom
Left = 98
Height = 23
Top = 33
Width = 183
BorderSpacing.Left = 6
BorderSpacing.Top = 5
BorderSpacing.Bottom = 6
Width = 80
BorderSpacing.CellAlignVertical = ccaCenter
Caption = 'lblFpDbgConv'
Constraints.MinHeight = 23
Layout = tlCenter
end
object dropFpDbgConv: TComboBox
AnchorSideLeft.Control = lblFpDbgConv
AnchorSideLeft.Side = asrBottom
AnchorSideTop.Control = lblFpDbgConv
AnchorSideTop.Side = asrCenter
AnchorSideRight.Side = asrBottom
Left = 85
Height = 23
Top = 33
Width = 227
Anchors = [akTop, akLeft, akRight]
BorderSpacing.Left = 5
Constraints.MinWidth = 150
ItemHeight = 15
Style = csDropDownList
TabOrder = 1
end
object lblValFormatter: TLabel
AnchorSideTop.Side = asrCenter
Left = 0
Height = 23
Top = 61
Width = 80
BorderSpacing.CellAlignVertical = ccaCenter
Caption = 'lblValFormatter'
Constraints.MinHeight = 23
Layout = tlCenter
end
object dropValFormatter: TComboBox
AnchorSideLeft.Control = lblValFormatter
AnchorSideLeft.Side = asrBottom
AnchorSideTop.Control = lblValFormatter
AnchorSideTop.Side = asrCenter
AnchorSideRight.Control = Panel2
AnchorSideRight.Side = asrBottom
Left = 85
Height = 23
Top = 61
Width = 196
Anchors = [akTop, akLeft, akRight]
BorderSpacing.Left = 5
Constraints.MinWidth = 150
ItemHeight = 15
Style = csDropDownList
TabOrder = 2
end
end
end
end
@ -250,5 +287,539 @@ object WatchPropertyDlg: TWatchPropertyDlg
ClientHeight = 407
ClientWidth = 551
TabOrder = 1
inherited ToolBar1: TToolBar
Width = 551
inherited ToolButton2: TToolButton
Height = 22
end
inherited ToolButton4: TToolButton
Height = 22
end
inherited ToolButton12: TToolButton
Height = 22
end
inherited ToolButton13: TToolButton
Height = 22
end
inherited ToolButton14: TToolButton
Height = 22
end
inherited ToolButton15: TToolButton
Height = 22
end
inherited ToolButton16: TToolButton
Height = 22
end
inherited ToolButton17: TToolButton
Height = 22
end
end
inherited PanelNum: TPanel
AnchorSideLeft.Control = DisplayFormatFrame1
AnchorSideRight.Control = DisplayFormatFrame1
Width = 551
ClientWidth = 551
inherited Spacer1: TLabel
Width = 99
end
inherited Spacer2: TLabel
Left = 103
Width = 448
end
inherited DividerBevelNum: TDividerBevel
Width = 551
end
inherited lbOverrideNumBase: TLabel
Width = 81
end
inherited PanelNumBase: TPanel
Left = 103
Width = 448
ClientWidth = 448
inherited rbNumDec: TRadioButton
Width = 75
end
inherited rbNumHex: TRadioButton
Left = 75
Width = 74
end
inherited rbNumOct: TRadioButton
Left = 149
Width = 75
end
inherited rbNumBin: TRadioButton
Left = 224
Width = 75
end
inherited rbNumChar: TRadioButton
Left = 299
Width = 74
end
inherited Label3: TLabel
Left = 373
Width = 75
end
end
inherited PanelNumSign: TPanel
Left = 103
Width = 448
ClientWidth = 448
inherited rbSignAuto: TRadioButton
Width = 149
end
inherited rbSignSigned: TRadioButton
Left = 149
Width = 150
end
inherited rbSignUnsigned: TRadioButton
Left = 299
Width = 149
end
end
inherited PanelNumDigits: TPanel
Left = 103
Width = 448
ClientWidth = 448
inherited DigitSpacer2: TLabel
Width = 299
end
inherited DigitSpacer1: TLabel
Left = 299
Width = 149
end
inherited lbNumDigits: TLabel
Left = 299
end
inherited SpinDigits: TSpinEdit
Left = 369
Width = 74
end
inherited cbNumSeparator: TCheckBox
Width = 295
end
inherited PanelNumSepGroup: TPanel
Width = 203
ClientWidth = 203
inherited rbNumSepNone: TRadioButton
Width = 48
end
inherited rbNumSepByte: TRadioButton
Left = 54
Width = 46
end
inherited rbNumSepWord: TRadioButton
Left = 102
Width = 48
end
inherited rbNumSepLong: TRadioButton
Left = 152
Width = 47
end
end
inherited Shape13: TShape
Left = 295
end
end
inherited Shape10: TShape
Left = 99
end
inherited Shape11: TShape
Left = 99
end
inherited Shape12: TShape
Left = 99
end
end
inherited PanelNum2: TPanel
AnchorSideLeft.Control = DisplayFormatFrame1
AnchorSideRight.Control = DisplayFormatFrame1
Width = 551
ClientWidth = 551
inherited Spacer13: TLabel
Width = 99
end
inherited Spacer14: TLabel
Left = 103
Width = 448
end
inherited DividerBevelNum2: TDividerBevel
Width = 551
end
inherited lbOverrideNum2Base: TLabel
Width = 81
end
inherited PanelNum2Visible: TPanel
Left = 103
Width = 448
ClientWidth = 448
inherited cbNum2Visibile: TCheckBox
Width = 448
end
end
inherited PanelNum2All: TPanel
Left = 103
Width = 448
ClientWidth = 448
inherited PanelNum2Base: TPanel
Width = 448
ClientWidth = 448
inherited rbNum2Dec: TRadioButton
Width = 75
end
inherited rbNum2Hex: TRadioButton
Left = 75
Width = 74
end
inherited rbNum2Oct: TRadioButton
Left = 149
Width = 75
end
inherited rbNum2Bin: TRadioButton
Left = 224
Width = 75
end
inherited rbNum2Char: TRadioButton
Left = 299
Width = 74
end
inherited Label1: TLabel
Left = 373
Height = 1
Width = 75
end
end
inherited PanelNum2Sign: TPanel
Width = 448
ClientWidth = 448
inherited rbSign2Auto: TRadioButton
Width = 149
end
inherited rbSign2Signed: TRadioButton
Left = 149
Width = 150
end
inherited rbSign2Unsigned: TRadioButton
Left = 299
Width = 149
end
end
inherited PanelNum2Digits: TPanel
Width = 448
ClientWidth = 448
inherited DigitSpacer4: TLabel
Width = 299
end
inherited DigitSpacer3: TLabel
Left = 299
Width = 149
end
inherited lbNum2Digits: TLabel
Left = 299
end
inherited Spin2Digits: TSpinEdit
Left = 375
Width = 68
end
inherited cbNum2Separator: TCheckBox
Width = 299
end
inherited PanelNum2SepGroup: TPanel
Width = 234
ClientWidth = 234
inherited rbNum2SepNone: TRadioButton
Width = 56
end
inherited rbNum2SepByte: TRadioButton
Left = 62
Width = 53
end
inherited rbNum2SepWord: TRadioButton
Left = 117
Width = 56
end
inherited rbNum2SepLong: TRadioButton
Left = 175
Width = 55
end
end
end
end
end
inherited PanelEnum: TPanel
AnchorSideLeft.Control = DisplayFormatFrame1
AnchorSideRight.Control = DisplayFormatFrame1
Width = 551
ClientWidth = 551
inherited Spacer3: TLabel
Width = 99
end
inherited Spacer4: TLabel
Left = 103
Width = 448
end
inherited DividerBevelEnum: TDividerBevel
Width = 551
end
inherited lbOverrideEnum: TLabel
Width = 81
end
inherited PanelEnumRb1: TPanel
Left = 103
Width = 448
ClientWidth = 448
inherited rbEnumName: TRadioButton
Width = 149
end
inherited rbEnumOrd: TRadioButton
Left = 149
Width = 150
end
inherited rbEnumNameAndOrd: TRadioButton
Left = 299
Width = 149
end
end
inherited PanelENumBase: TPanel
Left = 103
Width = 448
ClientWidth = 448
inherited rbENumDec: TRadioButton
Width = 75
end
inherited rbENumHex: TRadioButton
Left = 75
Width = 74
end
inherited rbENumOct: TRadioButton
Left = 149
Width = 75
end
inherited rbENumBin: TRadioButton
Left = 224
Width = 75
end
inherited rbENumChar: TRadioButton
Left = 299
Width = 74
end
inherited cbEnumSign: TCheckBox
Left = 373
Width = 75
end
inherited lbEnumBaseSpace: TLabel
Width = 75
end
inherited Shape18: TShape
Left = 369
end
end
inherited Shape16: TShape
Left = 99
end
inherited Shape17: TShape
Left = 99
end
end
inherited PanelFloat: TPanel
AnchorSideLeft.Control = DisplayFormatFrame1
AnchorSideRight.Control = DisplayFormatFrame1
Width = 551
ClientWidth = 551
inherited Spacer5: TLabel
Width = 99
end
inherited Spacer6: TLabel
Left = 103
Width = 448
end
inherited DividerBevelFloat: TDividerBevel
Width = 551
end
inherited lbOverrideFloat: TLabel
Width = 81
end
inherited PanelFloatRb: TPanel
Left = 103
Width = 448
ClientWidth = 448
inherited rbFloatPoint: TRadioButton
Width = 149
end
inherited rbFloatScience: TRadioButton
Left = 149
Width = 150
end
inherited lbFloatPrec: TLabel
Left = 299
end
inherited SpinFloatDigits: TSpinEdit
Left = 361
Width = 82
end
end
end
inherited PanelStruct: TPanel
AnchorSideLeft.Control = DisplayFormatFrame1
AnchorSideRight.Control = DisplayFormatFrame1
Width = 551
ClientWidth = 551
inherited Spacer7: TLabel
Width = 99
end
inherited Spacer8: TLabel
Left = 103
Width = 448
end
inherited DividerBevelStruct: TDividerBevel
Width = 551
end
inherited lbOverrideStruct: TLabel
Width = 81
end
inherited PanelStructFld: TPanel
Left = 103
Width = 448
ClientWidth = 448
inherited rbStructValOnly: TRadioButton
Width = 149
end
inherited rbStructFields: TRadioButton
Left = 149
Width = 150
end
inherited rbStructFull: TRadioButton
Left = 299
Width = 149
end
end
inherited PanelStructPointer: TPanel
Left = 103
Width = 448
ClientWidth = 448
inherited rbStructAddrOff: TRadioButton
Width = 149
end
inherited rbStructAddrOn: TRadioButton
Left = 149
Width = 150
end
inherited rbStructAddrOnly: TRadioButton
Left = 299
Width = 149
end
end
end
inherited PanelPointer: TPanel
AnchorSideLeft.Control = DisplayFormatFrame1
AnchorSideRight.Control = DisplayFormatFrame1
Width = 551
ClientWidth = 551
inherited Spacer9: TLabel
Width = 99
end
inherited Spacer10: TLabel
Left = 103
Width = 448
end
inherited DividerBevelPointerDeref: TDividerBevel
Width = 551
end
inherited lbOverridePointerDeref: TLabel
Width = 81
end
inherited PanelPointerDeref: TPanel
Left = 103
Width = 448
ClientWidth = 448
inherited rbPointerDerefOn: TRadioButton
Width = 149
end
inherited rbPointerDerefOff: TRadioButton
Left = 149
Width = 150
end
inherited rbPointerDerefOnly: TRadioButton
Left = 299
Width = 149
end
end
end
inherited PanelAddressFormat: TPanel
AnchorSideLeft.Control = DisplayFormatFrame1
AnchorSideRight.Control = DisplayFormatFrame1
Width = 551
ClientWidth = 551
inherited Spacer11: TLabel
Width = 99
end
inherited Spacer12: TLabel
Left = 103
Width = 448
end
inherited DividerBevelAddressFormat: TDividerBevel
Width = 551
end
inherited lbOverrideAddressFormat: TLabel
Width = 81
end
inherited PanelAddressType: TPanel
Left = 103
Width = 448
ClientWidth = 448
inherited rbAddressPlain: TRadioButton
Width = 149
end
inherited rbAddressTyped: TRadioButton
Left = 149
Width = 150
end
inherited Label5: TLabel
Left = 299
Height = 1
Width = 149
end
end
inherited PanelAddressBase: TPanel
Left = 103
Width = 448
ClientWidth = 448
inherited rbAddrNumHex: TRadioButton
Width = 75
end
inherited rbAddrNumDec: TRadioButton
Left = 75
Width = 74
end
inherited rbAddrNumOct: TRadioButton
Left = 149
Width = 75
end
inherited rbAddrNumBin: TRadioButton
Left = 224
Width = 75
end
inherited lpAddrSpace: TLabel
Left = 299
Height = 1
Width = 74
end
inherited cbAddrSign: TCheckBox
Left = 373
Width = 75
end
end
end
inherited PanelMemDump: TPanel
AnchorSideLeft.Control = DisplayFormatFrame1
AnchorSideRight.Control = DisplayFormatFrame1
Width = 551
ClientWidth = 551
inherited DividerBevelMemDump: TDividerBevel
Width = 551
end
inherited cbMemDump: TCheckBox
Width = 541
end
end
end
end

View File

@ -51,8 +51,9 @@ uses
// LazDebuggerIntf
LazDebuggerIntf,
// IdeDebugger
Debugger, IdeDebuggerOpts, BaseDebugManager, IdeDebuggerStringConstants,
EnvDebuggerOptions, ProjectDebugLink, IdeDebuggerBackendValueConv, DisplayFormatConfigFrame;
Debugger, IdeDebuggerOpts, BaseDebugManager, IdeDebuggerStringConstants, EnvDebuggerOptions,
ProjectDebugLink, IdeDebuggerBackendValueConv, IdeDebuggerValueFormatter,
DisplayFormatConfigFrame;
type
@ -66,6 +67,8 @@ type
chkUseInstanceClass: TCheckBox;
DisplayFormatFrame1: TDisplayFormatFrame;
dropFpDbgConv: TComboBox;
dropValFormatter: TComboBox;
lblValFormatter: TLabel;
Panel2: TPanel;
Spacer1: TLabel;
lblFpDbgConv: TLabel;
@ -100,6 +103,7 @@ implementation
procedure TWatchPropertyDlg.btnOKClick(Sender: TObject);
var
Conv: TIdeDbgValueConvertSelector;
VFormatter: TIdeDbgValueFormatterSelector;
begin
if FMode = wpmDispFormat then begin
FDisplayFormat := DisplayFormatFrame1.DisplayFormat;
@ -143,6 +147,20 @@ begin
FWatch.DbgBackendConverter := Conv;
end;
if dropValFormatter.ItemIndex = 0 then
FWatch.DbgValueFormatter := nil
else
if dropValFormatter.ItemIndex = 1 then
FWatch.EvaluateFlags := FWatch.EvaluateFlags + [defSkipValueFormatter]
else begin
VFormatter := TIdeDbgValueFormatterSelector(dropValFormatter.Items.Objects[dropValFormatter.ItemIndex]);
if (DebuggerOptions.ValueFormatterConfig.IndexOf(VFormatter) < 0) and
(DbgProjectLink.ValueFormatterConfig.IndexOf(VFormatter) < 0)
then
VFormatter := nil;
FWatch.DbgValueFormatter := VFormatter;
end;
FWatch.Enabled := chkEnabled.Checked;
finally
DebugBoss.Watches.CurrentWatches.EndUpdate;
@ -239,6 +257,28 @@ begin
end;
end;
lblValFormatter.Caption := dlgVarFormatterDebugOptions;
dropValFormatter.AddItem(dlgBackendConvOptDefault, nil);
dropValFormatter.AddItem(dlgBackendConvOptDisabled, nil);
for i := 0 to DebuggerOptions.ValueFormatterConfig.Count - 1 do
dropValFormatter.AddItem(DebuggerOptions.ValueFormatterConfig.Items[i].Name, DebuggerOptions.ValueFormatterConfig.Items[i]);
for i := 0 to DbgProjectLink.ValueFormatterConfig.Count - 1 do
dropValFormatter.AddItem(DbgProjectLink.ValueFormatterConfig.Items[i].Name, DbgProjectLink.ValueFormatterConfig.Items[i]);
dropValFormatter.ItemIndex := 0;
if AWatch <> nil then begin
if defSkipValueFormatter in AWatch.EvaluateFlags then begin
dropValFormatter.ItemIndex := 1;
end
else
if AWatch.DbgValueFormatter <> nil then begin
i := dropValFormatter.Items.IndexOfObject(AWatch.DbgValueFormatter);
assert(i > 0, 'TWatchPropertyDlg.Create: i > 0');
if i > 0 then
dropValFormatter.ItemIndex := i;
end;
end;
ButtonPanel.OKButton.Caption:=lisBtnOk;
ButtonPanel.HelpButton.Caption:=lisMenuHelp;
ButtonPanel.CancelButton.Caption:=lisCancel;