1unit HistoryDlg;
2
3{$mode objfpc}{$H+}
4
5interface
6
7uses
8  Classes, SysUtils, ComCtrls, Debugger, DebuggerDlg, LazarusIDEStrConsts, Forms,
9  IDEWindowIntf, DebuggerStrConst,
10  BaseDebugManager, IDEImagesIntf, Dialogs;
11
12type
13
14  { THistoryDialog }
15
16  THistoryDialog = class(TDebuggerDlg)
17    lvHistory: TListView;
18    OpenDialog1: TOpenDialog;
19    SaveDialog1: TSaveDialog;
20    tbMakeSnap: TToolButton;
21    ToolBar1: TToolBar;
22    tbHistorySelected: TToolButton;
23    tbPower: TToolButton;
24    tbClear: TToolButton;
25    ToolButton1: TToolButton;
26    tbHist: TToolButton;
27    tbSnap: TToolButton;
28    tbRemove: TToolButton;
29    ToolButton2: TToolButton;
30    tbExport: TToolButton;
31    ToolButton4: TToolButton;
32    tbImport: TToolButton;
33    procedure lvHistoryDblClick(Sender: TObject);
34    procedure lvHistorySelectItem(Sender: TObject; {%H-}Item: TListItem; {%H-}Selected: Boolean);
35    procedure tbClearClick(Sender: TObject);
36    procedure tbHistClick(Sender: TObject);
37    procedure tbHistorySelectedClick(Sender: TObject);
38    procedure tbMakeSnapClick(Sender: TObject);
39    procedure tbPowerClick(Sender: TObject);
40    procedure tbRemoveClick(Sender: TObject);
41    procedure tbExportClick(Sender: TObject);
42    procedure tbImportClick(Sender: TObject);
43  private
44    FInSnapshotChanged: Boolean;
45    imgCurrentLine: Integer;
46    FPowerImgIdx, FPowerImgIdxGrey: Integer;
47    FEnabledImgIdx, FDisabledIdx: Integer;
48    procedure SnapshotChanged(Sender: TObject);
49    procedure UpdateToolbar;
50  protected
51    function  ColSizeGetter(AColId: Integer; var ASize: Integer): Boolean;
52    procedure ColSizeSetter(AColId: Integer; ASize: Integer);
53  public
54    { public declarations }
55    constructor Create(TheOwner: TComponent); override;
56    property SnapshotManager;
57  end;
58
59implementation
60
61{$R *.lfm}
62
63var
64  HistoryDlgWindowCreator: TIDEWindowCreator;
65
66const
67  COL_HISTORY_CUR    = 1;
68  COL_HISTORY_TIME   = 2;
69  COL_HISTORY_LOC    = 3;
70  COL_WIDTHS: Array[0..2] of integer = ( 25,  120, 250);
71
72function HistoryDlgColSizeGetter(AForm: TCustomForm; AColId: Integer; var ASize: Integer): Boolean;
73begin
74  Result := AForm is THistoryDialog;
75  if Result then
76    Result := THistoryDialog(AForm).ColSizeGetter(AColId, ASize);
77end;
78
79procedure HistoryDlgColSizeSetter(AForm: TCustomForm; AColId: Integer; ASize: Integer);
80begin
81  if AForm is THistoryDialog then
82    THistoryDialog(AForm).ColSizeSetter(AColId, ASize);
83end;
84
85{ THistoryDialog }
86
87procedure THistoryDialog.lvHistoryDblClick(Sender: TObject);
88begin
89  if (lvHistory.Items.Count = 0) or (lvHistory.Selected = nil) then exit;
90  if tbHist.Down then begin
91    if (SnapshotManager.HistoryIndex = lvHistory.Selected.Index) and
92       (SnapshotManager.HistorySelected)
93    then begin
94      SnapshotManager.HistorySelected := False;
95    end
96    else begin
97      SnapshotManager.HistoryIndex := lvHistory.Selected.Index;
98      SnapshotManager.HistorySelected := True;
99    end;
100  end else begin
101    if (SnapshotManager.SnapshotIndex = lvHistory.Selected.Index) and
102       (SnapshotManager.SnapshotSelected)
103    then begin
104      SnapshotManager.SnapshotSelected := False;
105    end
106    else begin
107      SnapshotManager.SnapshotIndex := lvHistory.Selected.Index;
108      SnapshotManager.SnapshotSelected := True;
109    end;
110  end;
111end;
112
113procedure THistoryDialog.lvHistorySelectItem(Sender: TObject; Item: TListItem;
114  Selected: Boolean);
115begin
116  UpdateToolbar;
117end;
118
119procedure THistoryDialog.tbClearClick(Sender: TObject);
120begin
121  if SnapshotManager <> nil
122  then SnapshotManager.Clear;
123end;
124
125procedure THistoryDialog.tbHistClick(Sender: TObject);
126begin
127  if (SnapshotManager = nil) or (FInSnapshotChanged) then exit;
128  if tbHistorySelected.Down then begin
129    if tbSnap.Down then SnapshotManager.SnapshotSelected := True;
130    if tbHist.Down then SnapshotManager.HistorySelected := True;
131  end;
132  SnapshotChanged(nil);
133end;
134
135procedure THistoryDialog.tbHistorySelectedClick(Sender: TObject);
136begin
137  if tbHistorySelected.Down
138  then tbHistorySelected.ImageIndex := FEnabledImgIdx
139  else tbHistorySelected.ImageIndex := FDisabledIdx;
140  if SnapshotManager = nil then exit;
141  if tbHist.Down
142  then SnapshotManager.HistorySelected := tbHistorySelected.Down
143  else SnapshotManager.SnapshotSelected := tbHistorySelected.Down
144end;
145
146procedure THistoryDialog.tbMakeSnapClick(Sender: TObject);
147begin
148  if (SnapshotManager = nil) or (SnapshotManager.Current = nil) then exit;
149  SnapshotManager.Current.AddToSnapshots;
150end;
151
152procedure THistoryDialog.tbPowerClick(Sender: TObject);
153begin
154  if tbPower.Down
155  then tbPower.ImageIndex := FPowerImgIdx
156  else tbPower.ImageIndex := FPowerImgIdxGrey;
157  if SnapshotManager <> nil
158  then SnapshotManager.Active := tbPower.Down;
159end;
160
161procedure THistoryDialog.tbRemoveClick(Sender: TObject);
162begin
163  if lvHistory.Selected = nil then exit;
164  if tbHist.Down then begin
165    SnapshotManager.History[lvHistory.Selected.Index].RemoveFromHistory;
166  end else begin
167    SnapshotManager.Snapshots[lvHistory.Selected.Index].RemoveFromSnapshots;
168  end;
169end;
170
171procedure THistoryDialog.tbExportClick(Sender: TObject);
172var
173  tl: TStringList;
174begin
175  if (SnapshotManager = nil) then exit;
176  if SaveDialog1.Execute then begin
177    tl := TStringList.Create;
178    tl.Text := SnapshotManager.GetAsXML;
179    tl.SaveToFile(SaveDialog1.FileName);
180    tl.Free;
181  end;
182end;
183
184procedure THistoryDialog.tbImportClick(Sender: TObject);
185var
186  tl: TStringList;
187begin
188  if (SnapshotManager = nil) then exit;
189  if OpenDialog1.Execute then begin
190    tl := TStringList.Create;
191    tl.LoadFromFile(OpenDialog1.FileName);
192    SnapshotManager.SetFromXML(tl.Text);
193    tl.Free;
194  end;
195end;
196
197procedure THistoryDialog.SnapshotChanged(Sender: TObject);
198var
199  i, j, cur: Integer;
200  Item: TListItem;
201  Lst: TSnapshotList;
202begin
203  if (SnapshotManager = nil) or FInSnapshotChanged then exit;
204
205  FInSnapshotChanged:= True;
206  try
207    UpdateToolbar;
208  finally
209    FInSnapshotChanged := False;
210  end;
211
212  j := -1;
213  lvHistory.BeginUpdate;
214  try
215    if tbSnap.Down
216    then begin
217      Lst := SnapshotManager.Snapshots;
218      if SnapshotManager.SnapshotSelected
219      then cur := SnapshotManager.SnapshotIndex
220      else cur := -1;
221    end else begin
222      Lst := SnapshotManager.History;
223      if SnapshotManager.HistorySelected
224      then cur := SnapshotManager.HistoryIndex
225      else cur := -1;
226    end;
227
228    i := Lst.Count;
229    while lvHistory.Items.Count > i do lvHistory.Items.Delete(i);
230    while lvHistory.Items.Count < i do begin
231      Item := lvHistory.Items.Add;
232      Item.SubItems.add('');
233      Item.SubItems.add('');
234    end;
235
236    if Lst.Count = 0 then exit;
237
238    for i := 0 to Lst.Count - 1 do begin
239      lvHistory.Items[i].Caption := '';
240      if (i = cur)
241      then begin
242        lvHistory.Items[i].ImageIndex := imgCurrentLine;
243        j := i;
244      end
245      else lvHistory.Items[i].ImageIndex := -1;
246
247      lvHistory.Items[i].SubItems[0] := TimeToStr(Lst[i].TimeStamp);
248      lvHistory.Items[i].SubItems[1] := Lst[i].LocationAsText;
249      lvHistory.Items[i].Data        := Lst[i];
250    end;
251
252  finally
253    lvHistory.EndUpdate;
254  end;
255  if j >= 0
256  then lvHistory.Items[j].MakeVisible(False);
257end;
258
259procedure THistoryDialog.UpdateToolbar;
260var
261  Lst: TSnapshotList;
262  Sel: Boolean;
263begin
264  if SnapshotManager.Snapshots.Count > 0 then begin
265    tbSnap.Enabled := True;
266  end else begin
267    tbSnap.Enabled := False;
268    tbHist.Down := True;
269  end;
270
271  if tbSnap.Down
272  then begin
273    Lst := SnapshotManager.Snapshots;
274    Sel := SnapshotManager.SnapshotSelected;
275  end else begin
276    Lst := SnapshotManager.History;
277    Sel := SnapshotManager.HistorySelected;
278  end;
279
280  tbHistorySelected.Enabled := Lst.Count > 0;
281  if not tbHistorySelected.Enabled
282  then tbHistorySelected.Down := False
283  else tbHistorySelected.Down := Sel;
284  tbHistorySelectedClick(tbHistorySelected);
285
286  tbClear.Enabled := (SnapshotManager.History.Count > 0) or (SnapshotManager.Snapshots.Count > 0);
287
288  tbMakeSnap.Enabled := (SnapshotManager.Current <> nil) and (not SnapshotManager.Current.IsSnapshot);
289  tbRemove.Enabled := lvHistory.Selected <> nil;
290end;
291
292function THistoryDialog.ColSizeGetter(AColId: Integer; var ASize: Integer): Boolean;
293begin
294  if (AColId - 1 >= 0) and (AColId - 1 < lvHistory.ColumnCount) then begin
295    ASize := lvHistory.Column[AColId - 1].Width;
296    Result := ASize <> COL_WIDTHS[AColId - 1];
297  end
298  else
299    Result := False;
300end;
301
302procedure THistoryDialog.ColSizeSetter(AColId: Integer; ASize: Integer);
303begin
304  case AColId of
305    COL_HISTORY_CUR:    lvHistory.Column[0].Width := ASize;
306    COL_HISTORY_TIME:   lvHistory.Column[1].Width := ASize;
307    COL_HISTORY_LOC:    lvHistory.Column[2].Width := ASize;
308  end;
309end;
310
311constructor THistoryDialog.Create(TheOwner: TComponent);
312var
313  i: Integer;
314begin
315  inherited Create(TheOwner);
316  FInSnapshotChanged := False;
317  Caption:= histdlgFormName;
318  lvHistory.Column[0].Caption := histdlgColumnCur;
319  lvHistory.Column[1].Caption := histdlgColumnTime;
320  lvHistory.Column[2].Caption := histdlgColumnLoc;
321
322  SnapshotNotification.OnChange  := @SnapshotChanged;
323  SnapshotNotification.OnCurrent := @SnapshotChanged;
324
325  imgCurrentLine := IDEImages.LoadImage('debugger_current_line');
326  lvHistory.SmallImages := IDEImages.Images_16;
327
328  ToolBar1.Images := IDEImages.Images_16;
329
330  FPowerImgIdx     := IDEImages.LoadImage('debugger_power');
331  FPowerImgIdxGrey := IDEImages.LoadImage('debugger_power_grey');
332  FEnabledImgIdx   := IDEImages.LoadImage('debugger_enable');
333  FDisabledIdx     := IDEImages.LoadImage('debugger_disable');
334
335  tbPower.Hint := histdlgBtnPowerHint;
336  tbHistorySelected.Hint := histdlgBtnEnableHint;
337
338  tbClear.ImageIndex := IDEImages.LoadImage('menu_clean');
339  tbClear.Hint  := histdlgBtnClearHint;
340
341  tbHist.ImageIndex := IDEImages.LoadImage('clock');
342  tbHist.Hint  := histdlgBtnShowHistHint;
343
344  tbSnap.ImageIndex := IDEImages.LoadImage('camera');
345  tbSnap.Hint  := histdlgBtnShowSnapHint;
346
347  tbMakeSnap.ImageIndex := IDEImages.LoadImage('camera_add');
348  tbMakeSnap.Hint  := histdlgBtnMakeSnapHint;
349
350  tbRemove.ImageIndex := IDEImages.LoadImage('laz_delete');
351  tbRemove.Hint  := histdlgBtnRemoveHint;
352
353  tbImport.ImageIndex := IDEImages.LoadImage('laz_open');
354  tbImport.Hint  := lisImport;
355
356  tbExport.ImageIndex := IDEImages.LoadImage('laz_save');
357  tbExport.Hint  := lisExport;
358
359  tbPowerClick(nil);
360  tbHistorySelectedClick(nil);
361
362  for i := low(COL_WIDTHS) to high(COL_WIDTHS) do
363    lvHistory.Column[i].Width := COL_WIDTHS[i];
364
365  OpenDialog1.Title := lisImport;
366  SaveDialog1.Title := lisExport;
367
368  OpenDialog1.Filter := Format('%s|*.xml|%s|*.*|', [dlgFilterXML, dlgFilterAll]);
369  SaveDialog1.Filter := OpenDialog1.Filter;
370end;
371
372initialization
373
374  HistoryDlgWindowCreator := IDEWindowCreators.Add(DebugDialogNames[ddtHistory]);
375  HistoryDlgWindowCreator.OnCreateFormProc := @CreateDebugDialog;
376  HistoryDlgWindowCreator.OnSetDividerSize := @HistoryDlgColSizeSetter;
377  HistoryDlgWindowCreator.OnGetDividerSize := @HistoryDlgColSizeGetter;
378  HistoryDlgWindowCreator.DividerTemplate.Add('HistoryColCur',      COL_HISTORY_CUR,  @drsHistoryColWidthCurrent);
379  HistoryDlgWindowCreator.DividerTemplate.Add('HistoryColTime',     COL_HISTORY_TIME, @drsHistoryColWidthTime);
380  HistoryDlgWindowCreator.DividerTemplate.Add('HistoryColLocation', COL_HISTORY_LOC,  @drsHistoryColWidthLocation);
381  HistoryDlgWindowCreator.CreateSimpleLayout;
382
383end.
384
385