DBG: extend watch-view window with a detailed view pane (inspect) for the selected value. based on issue #0021990 by Darius Blaszijk

git-svn-id: trunk@37259 -
This commit is contained in:
martin 2012-05-12 17:25:52 +00:00
parent dee0c332d7
commit 08be80ba31
4 changed files with 150 additions and 11 deletions

View File

@ -48,6 +48,8 @@ resourcestring
drsColWidthFunc = 'Function name column';
drsColWidthBrkPointImg = 'Break indication column';
drsWatchSplitterInspect = 'Inspect pane';
drsBreakPointColWidthFile = 'File/address column';
drsBreakPointColWidthLine = 'Line column';
drsBreakPointColWidthCondition = 'Condition column';

View File

@ -16,7 +16,7 @@ inherited WatchesDlg: TWatchesDlg
Left = 0
Height = 174
Top = 26
Width = 500
Width = 295
Align = alClient
Columns = <
item
@ -110,12 +110,59 @@ inherited WatchesDlg: TWatchesDlg
Action = actAddWatch
end
object ToolButtonProperties: TToolButton
Left = 200
Left = 223
Top = 2
Action = actProperties
end
object ToolButtonInspectView: TToolButton
Left = 200
Top = 2
Action = actToggleInspectSite
Style = tbsCheck
end
end
object mnuPopup: TPopupMenu[2]
object InspectSplitter: TSplitter[2]
Left = 295
Height = 174
Top = 26
Width = 5
Align = alRight
ResizeAnchor = akRight
Visible = False
end
object nbInspect: TNotebook[3]
Left = 300
Height = 174
Top = 26
Width = 200
PageIndex = 0
Align = alRight
TabOrder = 3
TabStop = True
object Page1: TPage
object InspectMemo: TMemo
Left = 0
Height = 158
Top = 16
Width = 200
Align = alClient
ReadOnly = True
ScrollBars = ssAutoBoth
TabOrder = 0
WantReturns = False
end
object InspectLabel: TLabel
Left = 0
Height = 16
Top = 0
Width = 200
Align = alTop
Caption = '...'
ParentColor = False
end
end
end
object mnuPopup: TPopupMenu[4]
left = 100
top = 96
object popAdd: TMenuItem
@ -167,7 +214,7 @@ inherited WatchesDlg: TWatchesDlg
Action = actCopyValue
end
end
object ActionList1: TActionList[3]
object ActionList1: TActionList[5]
left = 184
top = 88
object actPower: TAction
@ -245,5 +292,9 @@ inherited WatchesDlg: TWatchesDlg
Caption = 'actEvaluate'
OnExecute = actEvaluateExecute
end
object actToggleInspectSite: TAction
Caption = 'actToggleInspectSite'
OnExecute = actToggleInspectSiteExecute
end
end
end

View File

@ -39,8 +39,9 @@ interface
uses
Classes, Forms, Controls, math, sysutils, LazLoggerBase, Clipbrd,
IDEWindowIntf, Menus, ComCtrls, ActnList, IDEImagesIntf, LazarusIDEStrConsts, DebuggerStrConst,
Debugger, DebuggerDlg, BaseDebugManager;
IDEWindowIntf, Menus, ComCtrls, ActnList, ExtCtrls, StdCtrls, IDEImagesIntf,
LazarusIDEStrConsts, DebuggerStrConst, Debugger, DebuggerDlg,
BaseDebugManager;
type
@ -65,12 +66,17 @@ type
actCopyValue: TAction;
actInspect: TAction;
actEvaluate: TAction;
actToggleInspectSite: TAction;
actToggleCurrentEnable: TAction;
actPower: TAction;
ActionList1: TActionList;
actProperties: TAction;
InspectLabel: TLabel;
lvWatches: TListView;
InspectMemo: TMemo;
MenuItem1: TMenuItem;
nbInspect: TNotebook;
Page1: TPage;
popInspect: TMenuItem;
popEvaluate: TMenuItem;
popCopyName: TMenuItem;
@ -87,7 +93,9 @@ type
popDisableAll: TMenuItem;
popEnableAll: TMenuItem;
popDeleteAll: TMenuItem;
InspectSplitter: TSplitter;
ToolBar1: TToolBar;
ToolButtonInspectView: TToolButton;
ToolButtonProperties: TToolButton;
ToolButtonAdd: TToolButton;
ToolButtonPower: TToolButton;
@ -108,6 +116,7 @@ type
procedure actEvaluateExecute(Sender: TObject);
procedure actInspectExecute(Sender: TObject);
procedure actPowerExecute(Sender: TObject);
procedure actToggleInspectSiteExecute(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure lvWatchesDblClick(Sender: TObject);
@ -136,6 +145,7 @@ type
procedure WatchUpdate(const ASender: TWatches; const AWatch: TWatch);
procedure WatchRemove(const ASender: TWatches; const AWatch: TWatch);
procedure UpdateInspectPane;
procedure UpdateItem(const AItem: TListItem; const AWatch: TWatch);
procedure UpdateAll;
procedure DisableAllActions;
@ -166,7 +176,8 @@ var
const
COL_WATCH_EXPR = 1;
COL_WATCH_VALUE = 2;
COL_WIDTHS: Array[0..1] of integer = ( 100, 200);
COL_SPLITTER_INSPECT = 3;
COL_WIDTHS: Array[0..2] of integer = ( 100, 200, 200);
function WatchesDlgColSizeGetter(AForm: TCustomForm; AColId: Integer; var ASize: Integer): Boolean;
begin
@ -184,12 +195,11 @@ end;
{ TWatchesDlg }
constructor TWatchesDlg.Create(AOwner: TComponent);
var
i: Integer;
begin
inherited Create(AOwner);
FWatchesInView := nil;
FStateFlags := [];
nbInspect.Visible := False;
WatchesNotification.OnAdd := @WatchAdd;
WatchesNotification.OnUpdate := @WatchUpdate;
@ -240,6 +250,9 @@ begin
actProperties.Caption:= liswlProperties;
actProperties.ImageIndex := IDEImages.LoadImage(16, 'menu_environment_options');
actToggleInspectSite.Caption:= liswlInspectPane;
actToggleInspectSite.ImageIndex := IDEImages.LoadImage(16, 'debugger_inspect');
actAddWatchPoint.Caption := lisWatchToWatchPoint;
actCopyName.Caption := lisLocalsDlgCopyName;
@ -253,8 +266,8 @@ begin
lvWatches.Columns[0].Caption:=liswlExpression;
lvWatches.Columns[1].Caption:=dlgValueColor;
for i := low(COL_WIDTHS) to high(COL_WIDTHS) do
lvWatches.Column[i].Width := COL_WIDTHS[i];
lvWatches.Column[0].Width := COL_WIDTHS[COL_WATCH_EXPR];
lvWatches.Column[1].Width := COL_WIDTHS[COL_WATCH_VALUE];
end;
function TWatchesDlg.GetSelected: TCurrentWatch;
@ -383,6 +396,8 @@ begin
actProperties.Enabled := ItemSelected;
actAddWatch.Enabled := True;
actPower.Enabled := True;
UpdateInspectPane;
end;
procedure TWatchesDlg.lvWatchesDblClick(Sender: TObject);
@ -418,6 +433,15 @@ begin
end;
end;
procedure TWatchesDlg.actToggleInspectSiteExecute(Sender: TObject);
begin
InspectSplitter.Visible := ToolButtonInspectView.Down;
nbInspect.Visible := ToolButtonInspectView.Down;
InspectSplitter.Left := nbInspect.Left - 1;
if ToolButtonInspectView.Down then
UpdateInspectPane;
end;
procedure TWatchesDlg.ContextChanged(Sender: TObject);
begin
DebugLn(DBG_DATA_MONITORS, ['DebugDataWindow: TWatchesDlg.ContextChanged ', DbgSName(Sender), ' Upd:', IsUpdating]);
@ -569,6 +593,11 @@ end;
function TWatchesDlg.ColSizeGetter(AColId: Integer; var ASize: Integer): Boolean;
begin
if AColId = COL_SPLITTER_INSPECT then begin
ASize := nbInspect.Width;
Result := ASize <> COL_WIDTHS[AColId - 1];
end
else
if (AColId - 1 >= 0) and (AColId - 1 < lvWatches.ColumnCount) then begin
ASize := lvWatches.Column[AColId - 1].Width;
Result := ASize <> COL_WIDTHS[AColId - 1];
@ -582,6 +611,7 @@ begin
case AColId of
COL_WATCH_EXPR: lvWatches.Column[0].Width := ASize;
COL_WATCH_VALUE: lvWatches.Column[1].Width := ASize;
COL_SPLITTER_INSPECT: nbInspect.Width := ASize;
end;
end;
@ -665,6 +695,60 @@ begin
end;
end;
procedure TWatchesDlg.UpdateInspectPane;
var
Watch: TCurrentWatch;
i: integer;
d: TWatchValue;
t: TDBGType;
begin
if not nbInspect.Visible then exit;
InspectMemo.Clear;
InspectLabel.Caption := '...';
if (lvWatches.Selected = nil) then begin
exit;
end;
Watch:=TCurrentWatch(lvWatches.Selected.Data);
d := Watch.Values[GetThreadId, GetStackframe];
t := d.TypeInfo;
InspectLabel.Caption := Watch.Expression;
if (t <> nil) and (t.Fields <> nil) and (t.Fields.Count > 0) and
(d.DisplayFormat in [wdfDefault, wdfStructure])
then begin
InspectMemo.WordWrap := False;
InspectMemo.Lines.BeginUpdate;
try
for i := 0 to t.Fields.Count - 1 do
case t.Fields[i].DBGType.Kind of
skSimple:
begin
if t.Fields[i].DBGType.Value.AsString='$0' then begin
if t.Fields[i].DBGType.TypeName='ANSISTRING' then
InspectMemo.Append(t.Fields[i].Name + ': ''''')
else
InspectMemo.Append(t.Fields[i].Name + ': nil');
end
else
InspectMemo.Append(t.Fields[i].Name + ': ' + t.Fields[i].DBGType.Value.AsString);
end;
skProcedure, skFunction: ;
else
InspectMemo.Append(t.Fields[i].Name + ': ' + t.Fields[i].DBGType.Value.AsString);
end;
finally
InspectMemo.Lines.EndUpdate;
end;
exit;
end;
InspectMemo.WordWrap := True;
InspectMemo.Text := d.Value;
end;
procedure TWatchesDlg.UpdateItem(const AItem: TListItem; const AWatch: TWatch);
function ClearMultiline(const AValue: ansistring): ansistring;
var
@ -829,6 +913,7 @@ initialization
WatchWindowCreator.OnGetDividerSize := @WatchesDlgColSizeGetter;
WatchWindowCreator.DividerTemplate.Add('ColumnWatchExpr', COL_WATCH_EXPR, @drsColWidthExpression);
WatchWindowCreator.DividerTemplate.Add('ColumnWatchValue', COL_WATCH_VALUE, @drsColWidthValue);
WatchWindowCreator.DividerTemplate.Add('SplitterWatchInspect', COL_SPLITTER_INSPECT, @drsWatchSplitterInspect);
WatchWindowCreator.CreateSimpleLayout;
DBG_DATA_MONITORS := DebugLogger.FindOrRegisterLogGroup('DBG_DATA_MONITORS' {$IFDEF DBG_DATA_MONITORS} , True {$ENDIF} );

View File

@ -1252,6 +1252,7 @@ resourcestring
liswlDIsableAll = 'D&isable All';
liswlENableAll = 'E&nable All';
liswlDeLeteAll = 'De&lete All';
liswlInspectPane = 'Inspect pane';
dlgOIMiscellaneous = 'Miscellaneous';
dlgOISpeedSettings = 'Speed settings';