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, // defFunctionCallRunAllThreads, //
defExtraDepth, // Evaluate 1 extra level of sub-elements => i.e., evaluate each nested sub-item defExtraDepth, // Evaluate 1 extra level of sub-elements => i.e., evaluate each nested sub-item
defSkipValConv, defSkipValConv,
defSkipValueFormatter, // Don't use any Valueformatter // not eval related
defMemDump, // Return Memory Dump, **instead** of value defMemDump, // Return Memory Dump, **instead** of value
// deprecated // deprecated
defNoTypeInfo, // No Typeinfo object will be returned // for structures that means a printed value will be returned 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.Enabled := Enabled;
Result.DisplayFormat := DisplayFormat; Result.DisplayFormat := DisplayFormat;
Result.DbgBackendConverter := DbgBackendConverter; Result.DbgBackendConverter := DbgBackendConverter;
Result.DbgValueFormatter := DbgValueFormatter;
Result.FDisplayName := ADispName; Result.FDisplayName := ADispName;
if (defClassAutoCast in EvaluateFlags) then if (defClassAutoCast in EvaluateFlags) then
Result.EvaluateFlags := Result.EvaluateFlags + [defClassAutoCast]; Result.EvaluateFlags := Result.EvaluateFlags + [defClassAutoCast];
@ -6933,7 +6934,6 @@ begin
if AConfig.GetValue(APath + 'SkipFpDbgConv', False) if AConfig.GetValue(APath + 'SkipFpDbgConv', False)
then Include(FEvaluateFlags, defSkipValConv) then Include(FEvaluateFlags, defSkipValConv)
else Exclude(FEvaluateFlags, defSkipValConv); else Exclude(FEvaluateFlags, defSkipValConv);
s := AConfig.GetValue(APath + 'FpDbgConv', ''); s := AConfig.GetValue(APath + 'FpDbgConv', '');
if s <> '' then begin if s <> '' then begin
if AConfig.GetValue(APath + 'FpDbgConvIsFromProject', False) then if AConfig.GetValue(APath + 'FpDbgConvIsFromProject', False) then
@ -6942,6 +6942,17 @@ begin
DbgBackendConverter := DebuggerOptions.BackendConverterConfig.ItemByName(s); DbgBackendConverter := DebuggerOptions.BackendConverterConfig.ItemByName(s);
end; 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/'); TIdeWatchValueList(FValueList).LoadDataFromXMLConfig(AConfig, APath + 'ValueList/');
end; end;
@ -6965,6 +6976,22 @@ begin
AConfig.SetDeleteValue(APath + 'FpDbgConvIsFromProject', AConfig.SetDeleteValue(APath + 'FpDbgConvIsFromProject',
(DbgProjectLink.BackendConverterConfig.IndexOf(DbgBackendConverter) >= 0), (DbgProjectLink.BackendConverterConfig.IndexOf(DbgBackendConverter) >= 0),
False); 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;
TIdeWatchValueList(FValueList).SaveDataToXMLConfig(AConfig, APath + 'ValueList/'); TIdeWatchValueList(FValueList).SaveDataToXMLConfig(AConfig, APath + 'ValueList/');
@ -7094,7 +7121,6 @@ begin
if AConfig.GetValue(APath + 'SkipFpDbgConv', False) if AConfig.GetValue(APath + 'SkipFpDbgConv', False)
then Include(FEvaluateFlags, defSkipValConv) then Include(FEvaluateFlags, defSkipValConv)
else Exclude(FEvaluateFlags, defSkipValConv); else Exclude(FEvaluateFlags, defSkipValConv);
s := AConfig.GetValue(APath + 'FpDbgConv', ''); s := AConfig.GetValue(APath + 'FpDbgConv', '');
if s <> '' then begin if s <> '' then begin
if AConfig.GetValue(APath + 'FpDbgConvIsFromProject', False) then if AConfig.GetValue(APath + 'FpDbgConvIsFromProject', False) then
@ -7102,6 +7128,17 @@ begin
else else
DbgBackendConverter := DebuggerOptions.BackendConverterConfig.ItemByName(s); DbgBackendConverter := DebuggerOptions.BackendConverterConfig.ItemByName(s);
end; 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; end;
procedure TCurrentWatch.SaveToXMLConfig(const AConfig: TXMLConfig; const APath: string); procedure TCurrentWatch.SaveToXMLConfig(const AConfig: TXMLConfig; const APath: string);
@ -7122,6 +7159,22 @@ begin
AConfig.SetDeleteValue(APath + 'FpDbgConvIsFromProject', AConfig.SetDeleteValue(APath + 'FpDbgConvIsFromProject',
(DbgProjectLink.BackendConverterConfig.IndexOf(DbgBackendConverter) >= 0), (DbgProjectLink.BackendConverterConfig.IndexOf(DbgBackendConverter) >= 0),
False); 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;
end; end;

View File

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

View File

@ -6,7 +6,7 @@ interface
uses uses
Classes, SysUtils, fgl, StrUtils, Classes, SysUtils, fgl, StrUtils,
Laz2_XMLCfg, Laz2_XMLCfg, LazClasses,
// LazDebuggerIntf // LazDebuggerIntf
LazDebuggerIntf, DbgUtilsTypePatternList, LazDebuggerIntf, DbgUtilsTypePatternList,
// DebuggerIntf // DebuggerIntf
@ -21,7 +21,7 @@ type
{ TIdeDbgValueFormatterSelector } { TIdeDbgValueFormatterSelector }
TIdeDbgValueFormatterSelector = class TIdeDbgValueFormatterSelector = class(TFreeNotifyingObject)
private private
FOriginalValue: TLazDbgIdeValFormatterOriginalValue; FOriginalValue: TLazDbgIdeValFormatterOriginalValue;
FValFormatter: ILazDbgIdeValueFormatterIntf; FValFormatter: ILazDbgIdeValueFormatterIntf;
@ -45,6 +45,11 @@ type
procedure LoadDataFromXMLConfig(const AConfig: TRttiXMLConfig; const APath: string); procedure LoadDataFromXMLConfig(const AConfig: TRttiXMLConfig; const APath: string);
procedure SaveDataToXMLConfig(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 IsMatchingTypeName(ATypeName: String): boolean;
function IsMatchingInheritedTypeName(ATypeName: String): boolean; function IsMatchingInheritedTypeName(ATypeName: String): boolean;
property FilterDisplayFormats: TValueDisplayFormats read FFilterDisplayFormats write SetFilterDisplayFormats; property FilterDisplayFormats: TValueDisplayFormats read FFilterDisplayFormats write SetFilterDisplayFormats;
@ -78,6 +83,8 @@ type
procedure LoadDataFromXMLConfig(const AConfig: TRttiXMLConfig; const APath: string); procedure LoadDataFromXMLConfig(const AConfig: TRttiXMLConfig; const APath: string);
procedure SaveDataToXMLConfig(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 Changed: Boolean read FChanged write SetChanged;
property OnChanged: TNotifyEvent read FOnChanged write FOnChanged; property OnChanged: TNotifyEvent read FOnChanged write FOnChanged;
public public
@ -212,6 +219,70 @@ begin
Def.Free; Def.Free;
end; 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; function TIdeDbgValueFormatterSelector.IsMatchingTypeName(ATypeName: String): boolean;
begin begin
Result := FMatchTypeNames.CheckTypeName(ATypeName); Result := FMatchTypeNames.CheckTypeName(ATypeName);
@ -306,6 +377,18 @@ begin
Def.Free; Def.Free;
end; 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; destructor TIdeDbgValueFormatterSelectorList.Destroy;
begin begin
FreeChangeNotifications; FreeChangeNotifications;
@ -316,61 +399,17 @@ function TIdeDbgValueFormatterSelectorList.FormatValue(
AWatchValue: IWatchResultDataIntf; ADisplayFormat: TWatchDisplayFormat; AWatchValue: IWatchResultDataIntf; ADisplayFormat: TWatchDisplayFormat;
AWatchResultPrinter: IWatchResultPrinter; out APrintedValue: String): Boolean; AWatchResultPrinter: IWatchResultPrinter; out APrintedValue: String): Boolean;
var var
i, j: Integer; i: Integer;
a: IWatchResultDataIntf;
f: TIdeDbgValueFormatterSelector; f: TIdeDbgValueFormatterSelector;
v: ILazDbgIdeValueFormatterIntf;
begin begin
for i := 0 to Count - 1 do begin for i := 0 to Count - 1 do begin
f := Items[i]; f := Items[i];
v := f.ValFormatter; if not f.MatchesAll(AWatchValue, ADisplayFormat) then
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
continue; continue;
if not f.IsMatchingTypeName(AWatchValue.TypeName) then begin Result := f.FormatValue(AWatchValue, ADisplayFormat, AWatchResultPrinter, APrintedValue);
if not f.MatchInherited then if Result 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;
exit; exit;
end;
end; end;
Result := False; Result := False;
end; end;

View File

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

View File

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

View File

@ -172,69 +172,106 @@ object WatchPropertyDlg: TWatchPropertyDlg
AnchorSideRight.Control = Spacer2 AnchorSideRight.Control = Spacer2
AnchorSideRight.Side = asrBottom AnchorSideRight.Side = asrBottom
Left = 287 Left = 287
Height = 62 Height = 84
Top = 0 Top = 0
Width = 281 Width = 281
Anchors = [akTop, akLeft, akRight] Anchors = [akTop, akLeft, akRight]
AutoSize = True AutoSize = True
BevelOuter = bvNone BevelOuter = bvNone
ChildSizing.HorizontalSpacing = 3 ChildSizing.HorizontalSpacing = 3
ChildSizing.EnlargeHorizontal = crsScaleChilds ChildSizing.VerticalSpacing = 5
ChildSizing.ShrinkHorizontal = crsScaleChilds
ChildSizing.Layout = cclLeftToRightThenTopToBottom ChildSizing.Layout = cclLeftToRightThenTopToBottom
ChildSizing.ControlsPerLine = 2 ChildSizing.ControlsPerLine = 1
ClientHeight = 62 ClientHeight = 84
ClientWidth = 281 ClientWidth = 281
TabOrder = 4 TabOrder = 4
object lblRepCount: TLabel object lblRepCount: TLabel
AnchorSideTop.Side = asrCenter AnchorSideTop.Side = asrCenter
Left = 0 Left = 0
Height = 15 Height = 23
Top = 9 Top = 5
Width = 92 Width = 80
BorderSpacing.Top = 5 BorderSpacing.Top = 5
BorderSpacing.CellAlignVertical = ccaCenter BorderSpacing.CellAlignVertical = ccaCenter
Caption = 'Repeat Count:' Caption = 'Repeat Count:'
Constraints.MinHeight = 23
Layout = tlCenter
ParentColor = False ParentColor = False
end end
object txtRepCount: TEdit object txtRepCount: TEdit
AnchorSideLeft.Control = lblRepCount
AnchorSideLeft.Side = asrBottom AnchorSideLeft.Side = asrBottom
AnchorSideTop.Control = lblRepCount
AnchorSideTop.Side = asrCenter
AnchorSideRight.Control = Panel2
AnchorSideRight.Side = asrBottom AnchorSideRight.Side = asrBottom
Left = 98 Left = 85
Height = 23 Height = 23
Top = 5 Top = 5
Width = 183 Width = 196
Alignment = taRightJustify Alignment = taRightJustify
BorderSpacing.Left = 6 Anchors = [akTop, akLeft, akRight]
BorderSpacing.Top = 5 BorderSpacing.Left = 5
TabOrder = 0 TabOrder = 0
Text = '0' Text = '0'
end end
object lblFpDbgConv: TLabel object lblFpDbgConv: TLabel
AnchorSideTop.Side = asrCenter AnchorSideTop.Side = asrCenter
Left = 0 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 Height = 23
Top = 33 Top = 33
Width = 183 Width = 80
BorderSpacing.Left = 6 BorderSpacing.CellAlignVertical = ccaCenter
BorderSpacing.Top = 5 Caption = 'lblFpDbgConv'
BorderSpacing.Bottom = 6 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 Constraints.MinWidth = 150
ItemHeight = 15 ItemHeight = 15
Style = csDropDownList Style = csDropDownList
TabOrder = 1 TabOrder = 1
end 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 end
end end
@ -250,5 +287,539 @@ object WatchPropertyDlg: TWatchPropertyDlg
ClientHeight = 407 ClientHeight = 407
ClientWidth = 551 ClientWidth = 551
TabOrder = 1 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
end end

View File

@ -51,8 +51,9 @@ uses
// LazDebuggerIntf // LazDebuggerIntf
LazDebuggerIntf, LazDebuggerIntf,
// IdeDebugger // IdeDebugger
Debugger, IdeDebuggerOpts, BaseDebugManager, IdeDebuggerStringConstants, Debugger, IdeDebuggerOpts, BaseDebugManager, IdeDebuggerStringConstants, EnvDebuggerOptions,
EnvDebuggerOptions, ProjectDebugLink, IdeDebuggerBackendValueConv, DisplayFormatConfigFrame; ProjectDebugLink, IdeDebuggerBackendValueConv, IdeDebuggerValueFormatter,
DisplayFormatConfigFrame;
type type
@ -66,6 +67,8 @@ type
chkUseInstanceClass: TCheckBox; chkUseInstanceClass: TCheckBox;
DisplayFormatFrame1: TDisplayFormatFrame; DisplayFormatFrame1: TDisplayFormatFrame;
dropFpDbgConv: TComboBox; dropFpDbgConv: TComboBox;
dropValFormatter: TComboBox;
lblValFormatter: TLabel;
Panel2: TPanel; Panel2: TPanel;
Spacer1: TLabel; Spacer1: TLabel;
lblFpDbgConv: TLabel; lblFpDbgConv: TLabel;
@ -100,6 +103,7 @@ implementation
procedure TWatchPropertyDlg.btnOKClick(Sender: TObject); procedure TWatchPropertyDlg.btnOKClick(Sender: TObject);
var var
Conv: TIdeDbgValueConvertSelector; Conv: TIdeDbgValueConvertSelector;
VFormatter: TIdeDbgValueFormatterSelector;
begin begin
if FMode = wpmDispFormat then begin if FMode = wpmDispFormat then begin
FDisplayFormat := DisplayFormatFrame1.DisplayFormat; FDisplayFormat := DisplayFormatFrame1.DisplayFormat;
@ -143,6 +147,20 @@ begin
FWatch.DbgBackendConverter := Conv; FWatch.DbgBackendConverter := Conv;
end; 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; FWatch.Enabled := chkEnabled.Checked;
finally finally
DebugBoss.Watches.CurrentWatches.EndUpdate; DebugBoss.Watches.CurrentWatches.EndUpdate;
@ -239,6 +257,28 @@ begin
end; end;
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.OKButton.Caption:=lisBtnOk;
ButtonPanel.HelpButton.Caption:=lisMenuHelp; ButtonPanel.HelpButton.Caption:=lisMenuHelp;
ButtonPanel.CancelButton.Caption:=lisCancel; ButtonPanel.CancelButton.Caption:=lisCancel;