From be4d6c3bcc7a99202cd11d45d58799e4b79cb31e Mon Sep 17 00:00:00 2001 From: Martin Date: Mon, 15 Apr 2024 20:25:34 +0200 Subject: [PATCH] IdeDebugger: refactor (Global)ValueFormatterSelectorList / (Global)ValueConverterSelectorList / DisplayFormat changed notify --- .../debuggerintf/dbgintfdebuggerbase.pp | 2 - ide/debugmanager.pas | 63 +++++------ ide/frames/project_displayformat_options.pas | 11 +- ide/frames/project_valconv_options.pas | 2 - ide/frames/project_valformatter_options.pas | 4 +- ide/main.pp | 8 +- .../frames/idedebugger_valconv_options.pas | 3 - .../idedebugger_valformatter_options.pas | 3 - .../idedebugger_displayformat_options.pas | 11 +- .../idedebuggerbackendvalueconv.pas | 29 ++--- ide/packages/idedebugger/idedebuggerbase.pas | 106 +++++++++++++++++- .../idedebugger/idedebuggerdisplayformats.pas | 36 ++++-- ide/packages/idedebugger/idedebuggerutils.pas | 45 +++++++- .../idedebugger/idedebuggervalueformatter.pas | 35 +++--- ide/packages/idedebugger/localsdlg.pp | 8 +- ide/packages/idedebugger/projectdebuglink.pas | 8 +- ide/packages/idedebugger/watchesdlg.pp | 12 +- 17 files changed, 260 insertions(+), 126 deletions(-) diff --git a/components/debuggerintf/dbgintfdebuggerbase.pp b/components/debuggerintf/dbgintfdebuggerbase.pp index 2ee43bc9e4..4f687d6414 100644 --- a/components/debuggerintf/dbgintfdebuggerbase.pp +++ b/components/debuggerintf/dbgintfdebuggerbase.pp @@ -1837,8 +1837,6 @@ type class property Debuggers[const AIndex: Integer]: TDebuggerClass read GetDebuggerClass; class property DebuggersByClassName[const AIndex: String]: TDebuggerClass read GetDebuggerClassByName; - public - procedure DoBackendConverterChanged; virtual; abstract; end; (* RegisterDebugger diff --git a/ide/debugmanager.pas b/ide/debugmanager.pas index 576d4fbec3..eba1e8bc71 100644 --- a/ide/debugmanager.pas +++ b/ide/debugmanager.pas @@ -115,6 +115,8 @@ type procedure DoProjectModified(Sender: TObject); private FAsmWindowShouldAutoClose: Boolean; + procedure DoDebugConfChanged(Sender: TObject); + procedure DoDisplayFormatChanged(Sender: TObject); procedure BreakAutoContinueTimer(Sender: TObject); procedure RunTimer(Sender: TObject); // Menu events @@ -233,7 +235,6 @@ type procedure DoRestoreDebuggerMarks(AnUnitInfo: TUnitInfo); procedure ClearDebugOutputLog; procedure ClearDebugEventsLog; - procedure DoBackendConverterChanged; override; function RequiredCompilerOpts(ATargetCPU, ATargetOS: String ): TDebugCompilerRequirements; override; @@ -1159,6 +1160,26 @@ begin FDebugger.Run; end; +procedure TDebugManager.DoDebugConfChanged(Sender: TObject); +var + d: TDebugDialogType; +begin + for d in TDebugDialogType do + if FDialogs[d] <> nil then + FDialogs[d].DebugConfigChanged; +end; + +procedure TDebugManager.DoDisplayFormatChanged(Sender: TObject); +begin + HintWatchPrinter.DisplayFormatResolver.FallBackFormats.Clear; + if DbgProjectLink.UseDisplayFormatConfigsFromIDE then + DebuggerOptions.DisplayFormatConfigs.AddToTargetedList(HintWatchPrinter.DisplayFormatResolver.FallBackFormats, dtfHint); + if DbgProjectLink.UseDisplayFormatConfigsFromProject then + DbgProjectLink.DisplayFormatConfigs.AddToTargetedList(HintWatchPrinter.DisplayFormatResolver.FallBackFormats, dtfHint); + + DoDebugConfChanged(Sender); +end; + procedure TDebugManager.RunTimer(Sender: TObject); begin FRunTimer.Enabled:=false; @@ -2112,6 +2133,13 @@ begin LazarusIDE.AddHandlerOnProjectClose(@DoProjectClose); FEventLogManager := TDebugEventLogManager.Create; + + DbgProjectLink.ValueFormatterConfig.AddChangeNotification(@DoDisplayFormatChanged); + DebuggerOptions.ValueFormatterConfig.AddChangeNotification(@DoDisplayFormatChanged); + DbgProjectLink.BackendConverterConfig.AddChangeNotification(@DoDebugConfChanged); + DebuggerOptions.BackendConverterConfig.AddChangeNotification(@DoDebugConfChanged); + DbgProjectLink.DisplayFormatConfigs.AddChangeNotification(@DoDebugConfChanged); + DebuggerOptions.DisplayFormatConfigs.AddChangeNotification(@DoDebugConfChanged); end; destructor TDebugManager.Destroy; @@ -2489,39 +2517,6 @@ begin FEventLogManager.ClearDebugEventsLog; end; -procedure TDebugManager.DoBackendConverterChanged; -var - d: TDebugDialogType; -begin - ValueConverterSelectorList.Lock; - - try - ValueConverterSelectorList.Clear; - ValueFormatterSelectorList.Clear; - if {(Project1 <> nil) and} (DbgProjectLink.UseBackendConverterFromProject) then - DbgProjectLink.BackendConverterConfig.AssignEnabledTo(ValueConverterSelectorList, True); - if (Project1 = nil) or (DbgProjectLink.UseBackendConverterFromIDE) then - DebuggerOptions.BackendConverterConfig.AssignEnabledTo(ValueConverterSelectorList, True); - - if {(Project1 <> nil) and} (DbgProjectLink.UseValueFormatterFromProject) then - DbgProjectLink.ValueFormatterConfig.AssignEnabledTo(ValueFormatterSelectorList, True); - if (Project1 = nil) or (DbgProjectLink.UseValueFormatterFromIDE) then - DebuggerOptions.ValueFormatterConfig.AssignEnabledTo(ValueFormatterSelectorList, True); - - HintWatchPrinter.DisplayFormatResolver.FallBackFormats.Clear; - if DbgProjectLink.UseDisplayFormatConfigsFromIDE then - DebuggerOptions.DisplayFormatConfigs.AddToTargetedList(HintWatchPrinter.DisplayFormatResolver.FallBackFormats, dtfHint); - if DbgProjectLink.UseDisplayFormatConfigsFromProject then - DbgProjectLink.DisplayFormatConfigs.AddToTargetedList(HintWatchPrinter.DisplayFormatResolver.FallBackFormats, dtfHint); - - for d in TDebugDialogType do - if FDialogs[d] <> nil then - FDialogs[d].DebugConfigChanged; - finally - ValueConverterSelectorList.Unlock; - end; -end; - function TDebugManager.RequiredCompilerOpts(ATargetCPU, ATargetOS: String ): TDebugCompilerRequirements; begin diff --git a/ide/frames/project_displayformat_options.pas b/ide/frames/project_displayformat_options.pas index 689796065e..e1b10c7bca 100644 --- a/ide/frames/project_displayformat_options.pas +++ b/ide/frames/project_displayformat_options.pas @@ -72,14 +72,14 @@ end; procedure TProjectDisplayFormatOptionsFrame.WriteSettings(AOptions: TAbstractIDEOptions); var - c, HasChg: Boolean; + HasChg: Boolean; begin DisplayFormatDefaultsConfigFrame1.SaveConfig; - c := DbgProjectLink.DisplayFormatConfigs.Changed; DbgProjectLink.DisplayFormatConfigs.Changed := False; DbgProjectLink.DisplayFormatConfigs.Assign(FDisplayFormatConfig); // assign will trigger changed, if anything changed HasChg := + DbgProjectLink.DisplayFormatConfigs.Changed or (DbgProjectLink.UseDisplayFormatConfigsFromIDE <> chkUseGlobalList.Checked) or (DbgProjectLink.UseDisplayFormatConfigsFromProject <> chkUseProjList.Checked); @@ -87,12 +87,7 @@ begin DbgProjectLink.UseDisplayFormatConfigsFromIDE := chkUseGlobalList.Checked; DbgProjectLink.UseDisplayFormatConfigsFromProject := chkUseProjList.Checked; - if HasChg or DbgProjectLink.DisplayFormatConfigs.Changed then begin - if (DebugBossManager <> nil) then - DebugBossManager.DoBackendConverterChanged; - end - else - DbgProjectLink.DisplayFormatConfigs.Changed := c; + DbgProjectLink.DisplayFormatConfigs.Changed := HasChg; end; class function TProjectDisplayFormatOptionsFrame.SupportedOptionsClass: TAbstractIDEOptionsClass; diff --git a/ide/frames/project_valconv_options.pas b/ide/frames/project_valconv_options.pas index 35147dd911..2d25c40534 100644 --- a/ide/frames/project_valconv_options.pas +++ b/ide/frames/project_valconv_options.pas @@ -106,8 +106,6 @@ begin DbgProjectLink.BackendConverterConfig.Changed := True; end; - if (DebugBossManager <> nil) and HasChg then - DebugBossManager.DoBackendConverterChanged; end; class function TIdeProjectValConvOptionsFrame.SupportedOptionsClass: TAbstractIDEOptionsClass; diff --git a/ide/frames/project_valformatter_options.pas b/ide/frames/project_valformatter_options.pas index f1748c6174..8c7efe8009 100644 --- a/ide/frames/project_valformatter_options.pas +++ b/ide/frames/project_valformatter_options.pas @@ -86,13 +86,11 @@ begin DbgProjectLink.UseValueFormatterFromIDE := chkUseGlobalList.Checked; DbgProjectLink.UseValueFormatterFromProject := chkUseProjList.Checked; - if FValFormatList.Changed then begin + if FValFormatList.Changed or HasChg then begin DbgProjectLink.ValueFormatterConfig.Assign(FValFormatList); DbgProjectLink.ValueFormatterConfig.Changed := True; end; - if (DebugBossManager <> nil) and HasChg then - DebugBossManager.DoBackendConverterChanged; end; class function TIdeProjectValueFormatterOptionsFrame.SupportedOptionsClass: TAbstractIDEOptionsClass; diff --git a/ide/main.pp b/ide/main.pp index 1c28dc1790..26e23937c0 100644 --- a/ide/main.pp +++ b/ide/main.pp @@ -104,7 +104,7 @@ uses LazDebuggerGdbmi, GDBMIDebugger, RunParamsOpts, BaseDebugManager, DebugManager, debugger, DebuggerDlg, DebugAttachDialog, DbgIntfDebuggerBase, DbgIntfProcess, LazDebuggerIntf, LazDebuggerIntfBaseTypes, - idedebuggerpackage, FpDebugValueConvertors, IdeDebuggerBackendValueConv, + idedebuggerpackage, FpDebugValueConvertors, IdeDebuggerBackendValueConv, IdeDebuggerBase, // packager PackageSystem, PkgManager, BasePkgManager, LPKCache, // source editing @@ -1417,8 +1417,6 @@ begin DebuggerOptions.PrimaryConfigPath := GetPrimaryConfigPath; DebuggerOptions.CreateConfig; DebuggerOptions.Load; - if DebugBoss <> nil then - DebugBoss.DoBackendConverterChanged; Assert(InputHistories = nil, 'TMainIDE.LoadGlobalOptions: InputHistories is already assigned.'); InputHistoriesSO := TInputHistoriesWithSearchOpt.Create; @@ -11513,7 +11511,7 @@ begin if (ResData <> nil) and not( (ResData.ValueKind = rdkPrePrinted) and (FHintWatchData.WatchValue.TypeInfo <> nil) ) then begin - if not ValueFormatterSelectorList.FormatValue(ResData, + if not GlobalValueFormatterSelectorList.FormatValue(ResData, DispFormat, WatchPrinter, ResultText) then begin ResultText := WatchPrinter.PrintWatchValue(ResData, DispFormat); @@ -11525,7 +11523,7 @@ begin end else begin if (FHintWatchData.WatchValue.TypeInfo = nil) or - not ValueFormatterSelectorList.FormatValue(FHintWatchData.WatchValue.TypeInfo, + not GlobalValueFormatterSelectorList.FormatValue(FHintWatchData.WatchValue.TypeInfo, FHintWatchData.WatchValue.Value, DispFormat, ResultText) then begin ResultText := FHintWatchData.WatchValue.Value; diff --git a/ide/packages/idedebugger/frames/idedebugger_valconv_options.pas b/ide/packages/idedebugger/frames/idedebugger_valconv_options.pas index 49706a96a0..70783bcd28 100644 --- a/ide/packages/idedebugger/frames/idedebugger_valconv_options.pas +++ b/ide/packages/idedebugger/frames/idedebugger_valconv_options.pas @@ -74,9 +74,6 @@ begin if FValConvList.Changed then begin DebuggerOptions.BackendConverterConfig.Assign(FValConvList); DebuggerOptions.BackendConverterConfig.Changed := True; - - if DebugBossManager <> nil then - DebugBossManager.DoBackendConverterChanged; end; end; diff --git a/ide/packages/idedebugger/frames/idedebugger_valformatter_options.pas b/ide/packages/idedebugger/frames/idedebugger_valformatter_options.pas index 1968fd1ab9..87df2f7917 100644 --- a/ide/packages/idedebugger/frames/idedebugger_valformatter_options.pas +++ b/ide/packages/idedebugger/frames/idedebugger_valformatter_options.pas @@ -73,9 +73,6 @@ begin if FValFormatList.Changed then begin DebuggerOptions.ValueFormatterConfig.Assign(FValFormatList); DebuggerOptions.ValueFormatterConfig.Changed := True; - - if DebugBossManager <> nil then - DebugBossManager.DoBackendConverterChanged; end; end; diff --git a/ide/packages/idedebugger/idedebugger_displayformat_options.pas b/ide/packages/idedebugger/idedebugger_displayformat_options.pas index 3dc5fe4454..88066ae15f 100644 --- a/ide/packages/idedebugger/idedebugger_displayformat_options.pas +++ b/ide/packages/idedebugger/idedebugger_displayformat_options.pas @@ -65,20 +65,13 @@ begin end; procedure TIdeDbgDisplayFormatOptionsFrame.WriteSettings(AOptions: TAbstractIDEOptions); -var - c: Boolean; begin DisplayFormatDefaultsConfigFrame1.SaveConfig; - c := DebuggerOptions.DisplayFormatConfigs.Changed; DebuggerOptions.DisplayFormatConfigs.Changed := False; DebuggerOptions.DisplayFormatConfigs.Assign(FDisplayFormatConfig); // assign will trigger changed, if anything changed - if DebuggerOptions.DisplayFormatConfigs.Changed then begin - if (DebugBossManager <> nil) then - DebugBossManager.DoBackendConverterChanged; - end - else - DebuggerOptions.DisplayFormatConfigs.Changed := c; + // trigger chnage notification + DebuggerOptions.DisplayFormatConfigs.Changed := DebuggerOptions.DisplayFormatConfigs.Changed; end; class function TIdeDbgDisplayFormatOptionsFrame.SupportedOptionsClass: TAbstractIDEOptionsClass; diff --git a/ide/packages/idedebugger/idedebuggerbackendvalueconv.pas b/ide/packages/idedebugger/idedebuggerbackendvalueconv.pas index 5ace73f8d5..ce274a4d63 100644 --- a/ide/packages/idedebugger/idedebuggerbackendvalueconv.pas +++ b/ide/packages/idedebugger/idedebuggerbackendvalueconv.pas @@ -5,7 +5,7 @@ unit IdeDebuggerBackendValueConv; interface uses - Classes, SysUtils, fgl, Laz2_XMLCfg, LazClasses, lazCollections, + Classes, SysUtils, fgl, Laz2_XMLCfg, LazClasses, lazCollections, IdeDebuggerUtils, LazDebuggerValueConverter; type @@ -43,7 +43,7 @@ type { TIdeDbgValueConvertSelectorList } TIdeDbgValueConvertSelectorList = class( - specialize TFPGObjectList, + specialize TChangeNotificationGeneric< specialize TFPGObjectList >, ILazDbgValueConvertSelectorListIntf ) private @@ -75,9 +75,6 @@ type property OnChanged: TNotifyEvent read FOnChanged write FOnChanged; end; -var - ValueConverterSelectorList: TIdeDbgValueConvertSelectorList; - implementation { TIdeDbgValueConvertSelector } @@ -188,10 +185,12 @@ end; procedure TIdeDbgValueConvertSelectorList.SetChanged(AValue: Boolean); begin - if FChanged = AValue then Exit; - FChanged := AValue; - if FChanged and (FOnChanged <> nil) then - FOnChanged(Self); + if FChanged <> AValue then begin + FChanged := AValue; + if FChanged and (FOnChanged <> nil) then + FOnChanged(Self); + end; + CallChangeNotifications; end; constructor TIdeDbgValueConvertSelectorList.Create; @@ -202,6 +201,7 @@ end; destructor TIdeDbgValueConvertSelectorList.Destroy; begin + FreeChangeNotifications; inherited Destroy; FLock.Free; end; @@ -255,7 +255,8 @@ begin Add(obj) else obj.Free; - end + end; + CallChangeNotifications; end; procedure TIdeDbgValueConvertSelectorList.SaveDataToXMLConfig( @@ -281,13 +282,5 @@ begin Result := IdeItems[i]; end; -initialization - ValueConverterSelectorList := TIdeDbgValueConvertSelectorList.Create; - ValueConverterConfigList := ValueConverterSelectorList; - -finalization - ValueConverterConfigList := nil; - FreeAndNil(ValueConverterSelectorList); - end. diff --git a/ide/packages/idedebugger/idedebuggerbase.pas b/ide/packages/idedebugger/idedebuggerbase.pas index c5035367a8..18a8077965 100644 --- a/ide/packages/idedebugger/idedebuggerbase.pas +++ b/ide/packages/idedebugger/idedebuggerbase.pas @@ -8,7 +8,8 @@ interface uses Classes, SysUtils, LazClasses, LazLoggerBase, LazMethodList, IdeDebuggerWatchResult, IdeDebuggerBackendValueConv, - IdeDebuggerWatchResultJSon, DbgIntfDebuggerBase, DbgIntfMiscClasses, + IdeDebuggerWatchResultJSon, IdeDebuggerValueFormatter, + ProjectDebugLink, IdeDebuggerOpts, Project, DbgIntfDebuggerBase, DbgIntfMiscClasses, IdeDebuggerWatchValueIntf, LazDebuggerIntf, LazDebuggerTemplate, LazDebuggerIntfBaseTypes, LazDebuggerValueConverter, FpDebugConvDebugForJson; @@ -294,10 +295,108 @@ type destructor Destroy; override; end; + { TIdeGlobalDbgValueConvertSelectorList } + + TIdeGlobalDbgValueConvertSelectorList = class(TIdeDbgValueConvertSelectorList) + private + procedure ConfigChanged(Sender: TObject); + public + constructor Create; + destructor Destroy; override; + end; + + { TIdeDbgGlobalValueFormatterSelectorList } + + TIdeDbgGlobalValueFormatterSelectorList = class(TIdeDbgValueFormatterSelectorList) + private + procedure ConfigChanged(Sender: TObject); + public + constructor Create; + end; + +function GetGlobalValueConverterSelectorList: TIdeGlobalDbgValueConvertSelectorList; +function GetGlobalValueFormatterSelectorList: TIdeDbgGlobalValueFormatterSelectorList; + +property GlobalValueConverterSelectorList: TIdeGlobalDbgValueConvertSelectorList read GetGlobalValueConverterSelectorList; +property GlobalValueFormatterSelectorList: TIdeDbgGlobalValueFormatterSelectorList read GetGlobalValueFormatterSelectorList; + implementation var DBG_DATA_MONITORS: PLazLoggerLogGroup; + TheGlobalValueConverterSelectorList: TIdeGlobalDbgValueConvertSelectorList = nil; + TheGlobalValueFormatterSelectorList: TIdeDbgGlobalValueFormatterSelectorList = nil; + +function GetGlobalValueConverterSelectorList: TIdeGlobalDbgValueConvertSelectorList; +begin + if TheGlobalValueConverterSelectorList = nil then begin + TheGlobalValueConverterSelectorList := TIdeGlobalDbgValueConvertSelectorList.Create; + ValueConverterConfigList := TheGlobalValueConverterSelectorList; + end; + Result := TheGlobalValueConverterSelectorList; +end; + +function GetGlobalValueFormatterSelectorList: TIdeDbgGlobalValueFormatterSelectorList; +begin + if TheGlobalValueFormatterSelectorList = nil then + TheGlobalValueFormatterSelectorList := TIdeDbgGlobalValueFormatterSelectorList.Create; + Result := TheGlobalValueFormatterSelectorList; +end; + +{ TIdeGlobalDbgValueConvertSelectorList } + +procedure TIdeGlobalDbgValueConvertSelectorList.ConfigChanged(Sender: TObject); +begin + Lock; + try + Clear; + if {(Project1 <> nil) and} (DbgProjectLink.UseBackendConverterFromProject) then + DbgProjectLink.BackendConverterConfig.AssignEnabledTo(Self, True); + if (Project1 = nil) or (DbgProjectLink.UseBackendConverterFromIDE) then + DebuggerOptions.BackendConverterConfig.AssignEnabledTo(Self, True); + + CallChangeNotifications; + finally + Unlock; + end; +end; + +constructor TIdeGlobalDbgValueConvertSelectorList.Create; +begin + inherited Create; + + DbgProjectLink.BackendConverterConfig.AddChangeNotification(@ConfigChanged); + DebuggerOptions.BackendConverterConfig.AddChangeNotification(@ConfigChanged); + ConfigChanged(nil); +end; + +destructor TIdeGlobalDbgValueConvertSelectorList.Destroy; +begin + ValueConverterConfigList := nil; + inherited Destroy; +end; + +{ TIdeDbgGlobalValueFormatterSelectorList } + +procedure TIdeDbgGlobalValueFormatterSelectorList.ConfigChanged(Sender: TObject); +begin + Clear; + if {(Project1 <> nil) and} (DbgProjectLink.UseValueFormatterFromProject) then + DbgProjectLink.ValueFormatterConfig.AssignEnabledTo(Self, True); + if (Project1 = nil) or (DbgProjectLink.UseValueFormatterFromIDE) then + DebuggerOptions.ValueFormatterConfig.AssignEnabledTo(Self, True); + + CallChangeNotifications; +end; + +constructor TIdeDbgGlobalValueFormatterSelectorList.Create; +begin + inherited Create; + + DbgProjectLink.ValueFormatterConfig.AddChangeNotification(@ConfigChanged); + DebuggerOptions.ValueFormatterConfig.AddChangeNotification(@ConfigChanged); + ConfigChanged(nil); +end; { TWatchValue } @@ -1083,7 +1182,12 @@ begin end; initialization + GetGlobalValueConverterSelectorList; // init ValueConverterConfigList DBG_DATA_MONITORS := DebugLogger.FindOrRegisterLogGroup('DBG_DATA_MONITORS' {$IFDEF DBG_DATA_MONITORS} , True {$ENDIF} ); +finalization + FreeAndNil(TheGlobalValueConverterSelectorList); + FreeAndNil(TheGlobalValueFormatterSelectorList); + end. diff --git a/ide/packages/idedebugger/idedebuggerdisplayformats.pas b/ide/packages/idedebugger/idedebuggerdisplayformats.pas index 5491e13f4d..a3ed6d472d 100644 --- a/ide/packages/idedebugger/idedebuggerdisplayformats.pas +++ b/ide/packages/idedebugger/idedebuggerdisplayformats.pas @@ -10,7 +10,7 @@ uses // LazUtils Laz2_XMLCfg, Classes, fgl, // IdeDebugger - IdeDebuggerStringConstants; + IdeDebuggerStringConstants, IdeDebuggerUtils; type TDisplayFormatTarget = ( @@ -34,17 +34,20 @@ type { TDisplayFormatConfig } - TDisplayFormatConfig = class + TDisplayFormatConfig = class(specialize TChangeNotificationGeneric) private FDefaultDisplayFormats: array [TDisplayFormatTarget] of TWatchDisplayFormat; private FGLobalDefault: Boolean; FChanged: Boolean; FOnChanged: TNotifyEvent; + procedure DoChanged; function GetDefaultDisplayFormats(AnIndex: TDisplayFormatTarget): TWatchDisplayFormat; + procedure SetChanged(AValue: Boolean); procedure SetDefaultDisplayFormats(AnIndex: TDisplayFormatTarget; AValue: TWatchDisplayFormat); public constructor Create(AGLobalDefault: Boolean = False); + destructor Destroy; override; procedure Clear; procedure Assign(ASource: TDisplayFormatConfig); @@ -55,7 +58,7 @@ type property DefaultDisplayFormats[AnIndex: TDisplayFormatTarget]: TWatchDisplayFormat read GetDefaultDisplayFormats write SetDefaultDisplayFormats; default; - property Changed: Boolean read FChanged write FChanged; + property Changed: Boolean read FChanged write SetChanged; property OnChanged: TNotifyEvent read FOnChanged write FOnChanged; end; @@ -318,12 +321,26 @@ end; { TDisplayFormatConfig } +procedure TDisplayFormatConfig.DoChanged; +begin + if (FOnChanged <> nil) then + FOnChanged(Self); + CallChangeNotifications; +end; + function TDisplayFormatConfig.GetDefaultDisplayFormats(AnIndex: TDisplayFormatTarget ): TWatchDisplayFormat; begin Result := FDefaultDisplayFormats[AnIndex]; end; +procedure TDisplayFormatConfig.SetChanged(AValue: Boolean); +begin + FChanged := AValue; + if AValue then + CallChangeNotifications; +end; + procedure TDisplayFormatConfig.SetDefaultDisplayFormats(AnIndex: TDisplayFormatTarget; AValue: TWatchDisplayFormat); var @@ -333,8 +350,7 @@ begin FDefaultDisplayFormats[AnIndex] := AValue; if c then begin FChanged := True; - if (FOnChanged <> nil) then - FOnChanged(Self); + DoChanged; end; end; @@ -345,6 +361,12 @@ begin Clear; end; +destructor TDisplayFormatConfig.Destroy; +begin + inherited Destroy; + FreeChangeNotifications; +end; + procedure TDisplayFormatConfig.Clear; var i: TDisplayFormatTarget; @@ -365,8 +387,7 @@ begin end; if c then begin FChanged := True; - if (FOnChanged <> nil) then - FOnChanged(Self); + DoChanged; end; end; @@ -389,6 +410,7 @@ var begin for i in TDisplayFormatTarget do LoadDisplayFormatFromXMLConfig(AXMLCfg, APath + XmlDisplayFormatTargetNames[i] + '/', FDefaultDisplayFormats[i]); + CallChangeNotifications; end; procedure TDisplayFormatConfig.SaveToXml(AXMLCfg: TRttiXMLConfig; APath: String); diff --git a/ide/packages/idedebugger/idedebuggerutils.pas b/ide/packages/idedebugger/idedebuggerutils.pas index b2ba6da42d..67957059e3 100644 --- a/ide/packages/idedebugger/idedebuggerutils.pas +++ b/ide/packages/idedebugger/idedebuggerutils.pas @@ -5,7 +5,24 @@ unit IdeDebuggerUtils; interface uses - Classes, SysUtils; + Classes, SysUtils, LazMethodList; + +type + + { TChangeNotificationGeneric } + + generic TChangeNotificationGeneric<_BASE: TObject> = class(_BASE) + strict private + FChangeNotifications: TMethodList; + protected + procedure FreeChangeNotifications; + public + // destructor Destroy; override; // not supported by fpc + procedure AddChangeNotification(AHandler: TNotifyEvent); + procedure RemoveChangeNotification(AHandler: TNotifyEvent); + procedure CallChangeNotifications; + end; + function HexDigicCount(ANum: QWord; AByteSize: Integer = 0; AForceAddr: Boolean = False): integer; function QuoteText(AText: Utf8String): UTf8String; @@ -417,5 +434,31 @@ begin Result := GetExpressionForArrayElement(AnArrayExpression, IntToStr(AnIndex)); end; +{ TChangeNotificationGeneric } + +procedure TChangeNotificationGeneric.FreeChangeNotifications; +begin + FreeAndNil(FChangeNotifications); +end; + +procedure TChangeNotificationGeneric.AddChangeNotification(AHandler: TNotifyEvent); +begin + if FChangeNotifications = nil then + FChangeNotifications := TMethodList.Create; + FChangeNotifications.Add(TMethod(AHandler)); +end; + +procedure TChangeNotificationGeneric.RemoveChangeNotification(AHandler: TNotifyEvent); +begin + if FChangeNotifications <> nil then + FChangeNotifications.Remove(TMethod(AHandler)); +end; + +procedure TChangeNotificationGeneric.CallChangeNotifications; +begin + if FChangeNotifications <> nil then + FChangeNotifications.CallNotifyEvents(Self); +end; + end. diff --git a/ide/packages/idedebugger/idedebuggervalueformatter.pas b/ide/packages/idedebugger/idedebuggervalueformatter.pas index fd27d71d70..f13dacd29c 100644 --- a/ide/packages/idedebugger/idedebuggervalueformatter.pas +++ b/ide/packages/idedebugger/idedebuggervalueformatter.pas @@ -12,7 +12,8 @@ uses // DebuggerIntf DbgIntfDebuggerBase, // IdeIntf - IdeDebuggerValueFormatterIntf, IdeDebuggerWatchValueIntf, IdeDebuggerDisplayFormats; + IdeDebuggerValueFormatterIntf, IdeDebuggerWatchValueIntf, IdeDebuggerDisplayFormats, + IdeDebuggerUtils; type @@ -60,7 +61,9 @@ type { TIdeDbgValueFormatterSelectorList } - TIdeDbgValueFormatterSelectorList = class(specialize TFPGObjectList) + TIdeDbgValueFormatterSelectorList = class( + specialize TChangeNotificationGeneric< specialize TFPGObjectList > + ) private FChanged: Boolean; FDefaultsAdded: integer; @@ -78,6 +81,7 @@ type property Changed: Boolean read FChanged write SetChanged; property OnChanged: TNotifyEvent read FOnChanged write FOnChanged; public + destructor Destroy; override; function FormatValue(AWatchValue: IWatchResultDataIntf; ADisplayFormat: TWatchDisplayFormat; AWatchResultPrinter: IWatchResultPrinter; out APrintedValue: String @@ -93,10 +97,6 @@ type property DefaultsAdded: integer read FDefaultsAdded write FDefaultsAdded; end; -var - ValueFormatterSelectorList: TIdeDbgValueFormatterSelectorList; - - implementation { TIdeDbgValueFormatterSelector } @@ -227,12 +227,13 @@ end; procedure TIdeDbgValueFormatterSelectorList.SetChanged(AValue: Boolean); begin - if FChanged = AValue then - exit; - FChanged := AValue; + if FChanged <> AValue then begin + FChanged := AValue; - if FOnChanged <> nil then - FOnChanged(Self); + if FOnChanged <> nil then + FOnChanged(Self); + end; + CallChangeNotifications; end; procedure TIdeDbgValueFormatterSelectorList.Assign( @@ -287,6 +288,7 @@ begin Def := TIdeDbgValueFormatterSelectorList.Create; AConfig.ReadObject(APath+'Conf/', Self, Def); Def.Free; + CallChangeNotifications; end; procedure TIdeDbgValueFormatterSelectorList.SaveDataToXMLConfig( @@ -304,6 +306,12 @@ begin Def.Free; end; +destructor TIdeDbgValueFormatterSelectorList.Destroy; +begin + FreeChangeNotifications; + inherited Destroy; +end; + function TIdeDbgValueFormatterSelectorList.FormatValue( AWatchValue: IWatchResultDataIntf; ADisplayFormat: TWatchDisplayFormat; AWatchResultPrinter: IWatchResultPrinter; out APrintedValue: String): Boolean; @@ -421,10 +429,5 @@ begin Result := False; end; -initialization - ValueFormatterSelectorList := TIdeDbgValueFormatterSelectorList.Create; - -finalization - FreeAndNil(ValueFormatterSelectorList); end. diff --git a/ide/packages/idedebugger/localsdlg.pp b/ide/packages/idedebugger/localsdlg.pp index 6704a716c8..34325dc813 100644 --- a/ide/packages/idedebugger/localsdlg.pp +++ b/ide/packages/idedebugger/localsdlg.pp @@ -892,7 +892,7 @@ begin if (ResData <> nil) and not( (ResData.ValueKind = rdkPrePrinted) and (AWatchAbleResult.TypeInfo <> nil) ) then begin - if not ValueFormatterSelectorList.FormatValue(ResData, + if not GlobalValueFormatterSelectorList.FormatValue(ResData, DispFormat, FLocalsDlg.FWatchPrinter, Result) then begin Result := FLocalsDlg.FWatchPrinter.PrintWatchValue(ResData, DispFormat); @@ -900,7 +900,7 @@ begin end else begin if (AWatchAbleResult.TypeInfo = nil) or - not ValueFormatterSelectorList.FormatValue(AWatchAbleResult.TypeInfo, + not GlobalValueFormatterSelectorList.FormatValue(AWatchAbleResult.TypeInfo, AWatchAbleResult.Value, DispFormat, Result) then begin Result := AWatchAbleResult.Value; @@ -934,7 +934,7 @@ begin if (ResData <> nil) and not( (ResData.ValueKind = rdkPrePrinted) and (AWatchAbleResult.TypeInfo <> nil) ) then begin - if not ValueFormatterSelectorList.FormatValue(ResData, + if not GlobalValueFormatterSelectorList.FormatValue(ResData, DispFormat, FLocalsDlg.FWatchPrinter, WatchValueStr) then begin WatchValueStr := FLocalsDlg.FWatchPrinter.PrintWatchValue(ResData, DispFormat); @@ -942,7 +942,7 @@ begin end else begin if (AWatchAbleResult.TypeInfo = nil) or - not ValueFormatterSelectorList.FormatValue(AWatchAbleResult.TypeInfo, + not GlobalValueFormatterSelectorList.FormatValue(AWatchAbleResult.TypeInfo, AWatchAbleResult.Value, DispFormat, WatchValueStr) then begin WatchValueStr := AWatchAbleResult.Value; diff --git a/ide/packages/idedebugger/projectdebuglink.pas b/ide/packages/idedebugger/projectdebuglink.pas index 1a0db449a3..c6b7aa2cb3 100644 --- a/ide/packages/idedebugger/projectdebuglink.pas +++ b/ide/packages/idedebugger/projectdebuglink.pas @@ -172,8 +172,9 @@ begin FProject := AValue; if Assigned(FProject) then FProject.DebuggerLink := Self; - if DebugBossManager <> nil then - DebugBossManager.DoBackendConverterChanged; + FBackendConverterConfig.CallChangeNotifications; + FValueFormatterConfig.CallChangeNotifications; + FDisplayFormatConfigs.CallChangeNotifications; end; procedure TProjectDebugLink.SetStoreDebuggerClassConfInSession(AValue: boolean); @@ -293,8 +294,7 @@ end; procedure TProjectDebugLink.AfterReadProject; begin - if DebugBossManager <> nil then - DebugBossManager.DoBackendConverterChanged; + // end; procedure TProjectDebugLink.LoadFromLPI(aXMLConfig: TRttiXMLConfig; Path: string); diff --git a/ide/packages/idedebugger/watchesdlg.pp b/ide/packages/idedebugger/watchesdlg.pp index df6c16570d..d2749aafbc 100644 --- a/ide/packages/idedebugger/watchesdlg.pp +++ b/ide/packages/idedebugger/watchesdlg.pp @@ -1205,7 +1205,7 @@ begin if (d.ResultData <> nil) and not( (d.ResultData.ValueKind = rdkPrePrinted) and (t <> nil) ) then begin - if ValueFormatterSelectorList.FormatValue(d.ResultData, Watch.DisplayFormat, FWatchPrinter, s) + if GlobalValueFormatterSelectorList.FormatValue(d.ResultData, Watch.DisplayFormat, FWatchPrinter, s) then begin InspectMemo.WordWrap := True; InspectMemo.Text := s; @@ -1214,7 +1214,7 @@ begin end else if (t <> nil) and - ValueFormatterSelectorList.FormatValue(t, d.Value, Watch.DisplayFormat, s) + GlobalValueFormatterSelectorList.FormatValue(t, d.Value, Watch.DisplayFormat, s) then begin InspectMemo.WordWrap := True; InspectMemo.Text := s; @@ -1508,7 +1508,7 @@ begin if (ResData <> nil) and not( (ResData.ValueKind = rdkPrePrinted) and (AWatchAbleResult.TypeInfo <> nil) ) then begin - if not ValueFormatterSelectorList.FormatValue(ResData, + if not GlobalValueFormatterSelectorList.FormatValue(ResData, DispFormat, FWatchDlg.FWatchPrinter, Result) then begin Result := FWatchDlg.FWatchPrinter.PrintWatchValue(ResData, DispFormat); @@ -1516,7 +1516,7 @@ begin end else begin if (AWatchAbleResult.TypeInfo = nil) or - not ValueFormatterSelectorList.FormatValue(AWatchAbleResult.TypeInfo, + not GlobalValueFormatterSelectorList.FormatValue(AWatchAbleResult.TypeInfo, AWatchAbleResult.Value, DispFormat, Result) then begin Result := AWatchAbleResult.Value; @@ -1569,7 +1569,7 @@ begin not( (ResData.ValueKind = rdkPrePrinted) and (AWatchAbleResult.TypeInfo <> nil) ) then begin FWatchDlg.FWatchPrinter.FormatFlags := [rpfClearMultiLine]; - if not ValueFormatterSelectorList.FormatValue(ResData, + if not GlobalValueFormatterSelectorList.FormatValue(ResData, DispFormat, FWatchDlg.FWatchPrinter, WatchValueStr) then begin WatchValueStr := FWatchDlg.FWatchPrinter.PrintWatchValue(ResData, DispFormat); @@ -1588,7 +1588,7 @@ begin end else begin if (AWatchAbleResult.TypeInfo = nil) or - not ValueFormatterSelectorList.FormatValue(AWatchAbleResult.TypeInfo, + not GlobalValueFormatterSelectorList.FormatValue(AWatchAbleResult.TypeInfo, AWatchAbleResult.Value, DispFormat, WatchValueStr) then begin WatchValueStr := AWatchAbleResult.Value;