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