1
{ $Id: localsdlg.pp 23459 2010-01-15 02:41:46Z paul $ }
1
{ $Id: localsdlg.pp 36579 2012-04-05 14:20:15Z vincents $ }
2
2
{ ----------------------------------------------
3
3
localsdlg.pp - Overview of local variables
4
4
----------------------------------------------
6
6
@created(Thu Mar 14st WET 2002)
7
@lastmod($Date: 2010-01-15 02:41:46 +0000 (Fri, 15 Jan 2010) $)
7
@lastmod($Date: 2012-04-05 16:20:15 +0200 (Thu, 05 Apr 2012) $)
8
8
@author(Marc Weustink <marc@@dommelstein.net>)
10
10
This unit contains the Locals debugger dialog.
39
SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
40
ComCtrls, Debugger, DebuggerDlg;
39
SysUtils, Classes, Forms, ClipBrd, LCLProc, LazLoggerBase,
40
IDEWindowIntf, DebuggerStrConst,
41
ComCtrls, ActnList, Menus, BaseDebugManager, Debugger, DebuggerDlg;
43
47
TLocalsDlg = class(TDebuggerDlg)
51
actCopyValue: TAction;
53
ActionList1: TActionList;
44
54
lvLocals: TListView;
61
PopupMenu1: TPopupMenu;
62
procedure actCopyNameExecute(Sender: TObject);
63
procedure actCopyValueExecute(Sender: TObject);
64
procedure actEvaluateExecute(Sender: TObject);
65
procedure actInspectExecute(Sender: TObject);
66
procedure actInspectUpdate(Sender: TObject);
67
procedure actWathExecute(Sender: TObject);
47
FLocalsNotification: TIDELocalsNotification;
69
FUpdateFlags: set of (ufNeedUpdating);
48
70
procedure LocalsChanged(Sender: TObject);
49
procedure SetLocals(const AValue: TIDELocals);
71
function GetThreadId: Integer;
72
function GetSelectedThreads(Snap: TSnapshot): TThreads;
73
function GetStackframe: Integer;
74
function GetSelectedSnapshot: TSnapshot;
51
76
procedure DoBeginUpdate; override;
52
77
procedure DoEndUpdate; override;
78
function ColSizeGetter(AColId: Integer; var ASize: Integer): Boolean;
79
procedure ColSizeSetter(AColId: Integer; ASize: Integer);
54
81
constructor Create(AOwner: TComponent); override;
55
destructor Destroy; override;
57
property Locals: TIDELocals read FLocals write SetLocals;
82
property LocalsMonitor;
83
property ThreadsMonitor;
84
property CallStackMonitor;
85
property SnapshotManager;
66
94
LazarusIDEStrConsts;
97
DBG_DATA_MONITORS: PLazLoggerLogGroup;
98
LocalsDlgWindowCreator: TIDEWindowCreator;
102
COL_LOCALS_VALUE = 2;
103
COL_WIDTHS: Array[0..1] of integer = ( 50, 150);
105
function LocalsDlgColSizeGetter(AForm: TCustomForm; AColId: Integer; var ASize: Integer): Boolean;
107
Result := AForm is TLocalsDlg;
109
Result := TLocalsDlg(AForm).ColSizeGetter(AColId, ASize);
112
procedure LocalsDlgColSizeSetter(AForm: TCustomForm; AColId: Integer; ASize: Integer);
114
if AForm is TLocalsDlg then
115
TLocalsDlg(AForm).ColSizeSetter(AColId, ASize);
70
120
constructor TLocalsDlg.Create(AOwner: TComponent);
72
124
inherited Create(AOwner);
73
FLocalsNotification := TIDELocalsNotification.Create;
74
FLocalsNotification.AddReference;
75
FLocalsNotification.OnChange := @LocalsChanged;
125
LocalsNotification.OnChange := @LocalsChanged;
126
ThreadsNotification.OnCurrent := @LocalsChanged;
127
CallstackNotification.OnCurrent := @LocalsChanged;
128
SnapshotNotification.OnCurrent := @LocalsChanged;
76
130
Caption:= lisLocals;
77
lvLocals.Columns[0].Caption:= lisLocalsDlgName;
78
lvLocals.Columns[1].Caption:= lisLocalsDlgValue;
81
destructor TLocalsDlg.Destroy;
84
FLocalsNotification.OnChange := nil;
85
FLocalsNotification.ReleaseReference;
131
lvLocals.Columns[0].Caption:= lisName;
132
lvLocals.Columns[1].Caption:= lisValue;
133
actInspect.Caption := lisInspect;
134
actWath.Caption := lisWatch;
135
actEvaluate.Caption := lisEvaluateModify;
136
actCopyName.Caption := lisLocalsDlgCopyName;
137
actCopyValue.Caption := lisLocalsDlgCopyValue;
139
for i := low(COL_WIDTHS) to high(COL_WIDTHS) do
140
lvLocals.Column[i].Width := COL_WIDTHS[i];
143
procedure TLocalsDlg.actInspectUpdate(Sender: TObject);
145
(Sender as TAction).Enabled := Assigned(lvLocals.Selected);
148
procedure TLocalsDlg.actWathExecute(Sender: TObject);
151
Watch: TCurrentWatch;
153
S := lvLocals.Selected.Caption;
154
if DebugBoss.Watches.CurrentWatches.Find(S) = nil then
156
Watch := DebugBoss.Watches.CurrentWatches.Add(S);
157
Watch.Enabled := True;
159
DebugBoss.ViewDebugDialog(ddtWatches);
162
procedure TLocalsDlg.actInspectExecute(Sender: TObject);
164
DebugBoss.Inspect(lvLocals.Selected.Caption);
167
procedure TLocalsDlg.actEvaluateExecute(Sender: TObject);
169
DebugBoss.EvaluateModify(lvLocals.Selected.Caption);
172
procedure TLocalsDlg.actCopyNameExecute(Sender: TObject);
175
Clipboard.AsText := lvLocals.Selected.Caption;
179
procedure TLocalsDlg.actCopyValueExecute(Sender: TObject);
182
Clipboard.AsText := lvLocals.Selected.SubItems[0];
89
186
procedure TLocalsDlg.LocalsChanged(Sender: TObject);
92
189
List: TStringList;
195
if (ThreadsMonitor = nil) or (CallStackMonitor = nil) or (LocalsMonitor=nil) then begin
196
lvLocals.Items.Clear;
200
if IsUpdating then begin
201
DebugLn(DBG_DATA_MONITORS, ['DebugDataWindow: TLocalsDlg.LocalsChanged in IsUpdating']);
202
Include(FUpdateFlags, ufNeedUpdating);
205
Exclude(FUpdateFlags, ufNeedUpdating);
206
DebugLn(DBG_DATA_MONITORS, ['DebugDataMonitor: TLocalsDlg.LocalsChanged']);
208
if GetStackframe < 0 then begin // TODO need dedicated validity property
209
lvLocals.Items.Clear;
213
Snap := GetSelectedSnapshot;
216
Locals := LocalsMonitor.Snapshots[Snap][GetThreadId, GetStackframe];
217
Caption:= lisLocals + ' ('+ Snap.LocationAsText +')';
220
Locals := LocalsMonitor.CurrentLocalsList[GetThreadId, GetStackframe];
96
224
List := TStringList.Create;
102
230
lvLocals.Items.Clear;
231
Item := lvLocals.Items.Add;
233
Item.SubItems.add(lisLocalsNotEvaluated);
106
237
//Get existing items
107
238
for n := 0 to lvLocals.Items.Count - 1 do
115
246
// add/update entries
116
for n := 0 to FLocals.Count - 1 do
247
for n := 0 to Locals.Count - 1 do
118
idx := List.IndexOf(Uppercase(FLocals.Names[n]));
249
idx := List.IndexOf(Uppercase(Locals.Names[n]));
122
253
Item := lvLocals.Items.Add;
123
Item.Caption := FLocals.Names[n];
124
Item.SubItems.Add(FLocals.Values[n]);
254
Item.Caption := Locals.Names[n];
255
Item.SubItems.Add(Locals.Values[n]);
127
258
// Existing entry
128
259
Item := TListItem(List.Objects[idx]);
129
Item.SubItems[0] := FLocals.Values[n];
260
Item.SubItems[0] := Locals.Values[n];
130
261
List.Delete(idx);
146
procedure TLocalsDlg.SetLocals(const AValue: TIDELocals);
148
if FLocals = AValue then Exit;
154
FLocals.RemoveNotification(FLocalsNotification);
161
FLocals.AddNotification(FLocalsNotification);
164
LocalsChanged(FLocals);
277
function TLocalsDlg.GetThreadId: Integer;
282
if (ThreadsMonitor = nil) then exit;
283
Threads := GetSelectedThreads(GetSelectedSnapshot);
285
then Result := Threads.CurrentThreadId
289
function TLocalsDlg.GetSelectedThreads(Snap: TSnapshot): TThreads;
291
if ThreadsMonitor = nil then exit(nil);
293
then Result := ThreadsMonitor.CurrentThreads
294
else Result := ThreadsMonitor.Snapshots[Snap];
297
function TLocalsDlg.GetStackframe: Integer;
304
if (CallStackMonitor = nil) or (ThreadsMonitor = nil)
310
Snap := GetSelectedSnapshot;
311
Threads := GetSelectedThreads(Snap);
313
then tid := Threads.CurrentThreadId
317
then Stack := CallStackMonitor.Snapshots[Snap].EntriesForThreads[tid]
318
else Stack := CallStackMonitor.CurrentCallStackList.EntriesForThreads[tid];
321
then Result := Stack.CurrentIndex
325
function TLocalsDlg.GetSelectedSnapshot: TSnapshot;
328
if (SnapshotManager <> nil) and (SnapshotManager.SelectedEntry <> nil)
329
then Result := SnapshotManager.SelectedEntry;
170
332
procedure TLocalsDlg.DoBeginUpdate;
175
337
procedure TLocalsDlg.DoEndUpdate;
339
if ufNeedUpdating in FUpdateFlags then LocalsChanged(nil);
177
340
lvLocals.EndUpdate;
343
function TLocalsDlg.ColSizeGetter(AColId: Integer; var ASize: Integer): Boolean;
345
if (AColId - 1 >= 0) and (AColId - 1 < lvLocals.ColumnCount) then begin
346
ASize := lvLocals.Column[AColId - 1].Width;
347
Result := (ASize <> COL_WIDTHS[AColId - 1]) and (not lvLocals.Column[AColId - 1].AutoSize);
353
procedure TLocalsDlg.ColSizeSetter(AColId: Integer; ASize: Integer);
356
COL_LOCALS_NAME: lvLocals.Column[0].Width := ASize;
357
COL_LOCALS_VALUE: lvLocals.Column[1].Width := ASize;
363
LocalsDlgWindowCreator := IDEWindowCreators.Add(DebugDialogNames[ddtLocals]);
364
LocalsDlgWindowCreator.OnCreateFormProc := @CreateDebugDialog;
365
LocalsDlgWindowCreator.OnSetDividerSize := @LocalsDlgColSizeSetter;
366
LocalsDlgWindowCreator.OnGetDividerSize := @LocalsDlgColSizeGetter;
367
LocalsDlgWindowCreator.DividerTemplate.Add('LocalsName', COL_LOCALS_NAME, @drsColWidthName);
368
LocalsDlgWindowCreator.DividerTemplate.Add('LocalsValue', COL_LOCALS_VALUE, @drsColWidthValue);
369
LocalsDlgWindowCreator.CreateSimpleLayout;
371
DBG_DATA_MONITORS := DebugLogger.FindOrRegisterLogGroup('DBG_DATA_MONITORS' {$IFDEF DBG_DATA_MONITORS} , True {$ENDIF} );