unit BptDlg;

{$O+,F+,S-,V-}

interface

uses Objects, Drivers, Views, Dialogs;

const

  cmEditBreakpoint      = 1040;
  cmDeleteBreakpoint    = 1041;
  cmViewBreakpoint      = 1042;
  cmHackBreakpoint      = 1043;
  cmShowBreakpoint      = 1044;
  cmClearAllBreakpoints = 1045;
  cmModifyBreakpoint    = 1050;
  cmNewBreakpoint       = 1051;

type

  PBreakViewer = ^TBreakViewer;
  TBreakViewer = object(TListViewer)
    procedure ClearAll;
    procedure Delete;
    procedure Edit;
    function  GetText(Item: Integer; MaxLen: Integer): string; virtual;
    procedure HandleEvent(var Event: TEvent); virtual;
    procedure SetData(var Rec); virtual;
    procedure Update;
  end;

  PBreakDialog = ^TBreakDialog;
  TBreakDialog = object(TDialog)
    Viewer: PBreakViewer;
    constructor Init;
    constructor Load(var S: TStream);
    procedure HandleEvent(var Event: TEvent); virtual;
    procedure Store(var S: TStream);
  end;

  PEditBreakDialog = ^TEditBreakDialog;
  TEditBreakDialog = object(TDialog)
    constructor Init;
    procedure HandleEvent(var Event: TEvent); virtual;
  end;

const

  RBreakViewer: TStreamRec = (
    ObjType: 3012;
    VmtLink: Ofs(TypeOf(TBreakViewer)^);
    Load:    @TBreakViewer.Load;
    Store:   @TBreakViewer.Store
  );
  RBreakDialog: TStreamRec = (
    ObjType: 3013;
    VmtLink: Ofs(TypeOf(TBreakDialog)^);
    Load:    @TBreakDialog.Load;
    Store:   @TBreakDialog.Store
  );
  REditBreakDialog: TStreamRec = (
    ObjType: 3014;
    VmtLink: Ofs(TypeOf(TEditBreakDialog)^);
    Load:    @TEditBreakDialog.Load;
    Store:   @TEditBreakDialog.Store
  );

implementation

uses TDos, CompVars, FNames, Tracer, Editor, Utils, Controls, Context, StrNames;

procedure TBreakViewer.ClearAll;
begin
  DeleteAllBpts;
  Update;
end;

procedure TBreakViewer.Delete;
begin
  DeleteBpt(Focused);
  Update;
end;

procedure TBreakViewer.Edit;
var
  I: Word;
  P: PEditView;
  R: record
    Condition: PathStr;
    PassCount: Longint;
    FileName: PathStr;
    LineNumber: Longint;
  end;
  B: TBreakpoint;
begin
  if Focused < BptCount then
    B := BptArr[Focused]^
  else
  begin
    P := FindEditor(nil);
    if P <> nil then
      P^.SetBpt(B)
    else
    begin
      B.FileName := '';
      B.LineNumber := 1;
      B.Condition := '';
      B.PassCount := 0;
    end;
  end;
  R.FileName := B.FileName;
  R.LineNumber := B.LineNumber;
  R.Condition := B.Condition;
  R.PassCount := B.PassCount;
  if R.FileName <> '' then
    ConvertPath(R.FileName, 79);
  I := ExecDialog('EditBreakDialog', @R);
  if I <>cmCancel then
  begin
    FExpand(R.FileName, B.FileName);
    B.LineNumber := R.LineNumber;
    B.Condition := R.Condition;
    B.PassCount := R.PassCount;
    case I of
      cmModifyBreakpoint:
        SetBpt(Focused,B);
      cmNewBreakpoint:
        SetBpt(BptCount,B);
    end;
    Update;
  end;
end;

function TBreakViewer.GetText(Item: Integer; MaxLen: Integer): string;
var
  L: array[0..3] of Longint;
  Name: PathStr;
  S: string[79];
begin
  if Item >= BptCount then
    GetText := ''
  else
    with BptArr[Item]^ do
    begin
      Name := FileName;
      ConvertPath(Name, 24);
      L[0] := Longint(@Name);
      L[1] := LineNumber;
      L[2] := Longint(@Condition);
      L[3] := PassCount;
      FormatStr(S, '%-24s%5d  %-30s%5d', L);
      GetText := S;
    end;
end;

procedure TBreakViewer.HandleEvent(var Event: TEvent);
begin
  TListViewer.HandleEvent(Event);
  if (Event.What = evKeyDown) and (Event.KeyCode = kbDel) then
  begin
    Delete;
    ClearEvent(Event);
  end;
end;

procedure TBreakViewer.SetData(var Rec);
var
  I: Integer;
  P: PEditView;
  B: TBreakpoint;
begin
  SetRange(BptCount + 1);
  P := FindEditor(nil);
  if P <> nil then
  begin
    P^.SetBpt(B);
    I := FindBpt(B);
    if I < BptCount then
      FocusItem(I);
  end;
end;

procedure TBreakViewer.Update;
begin
  SetRange(BptCount + 1);
  DrawView;
  ConnectAllBpts;
end;

constructor TBreakDialog.Init;
var
  R: TRect;
  Control: PScrollBar;
begin
  R.Assign(3, 3, 76, 18);
  TDialog.Init(R, 'Breakpoints');
  Options := Options or ofCentered;
  R.Assign(70, 3, 71, 11);
  Control := New(PScrollBar, Init(R));
  Insert(Control);
  R.Assign(2, 3, 70, 11);
  Viewer := PBreakViewer(SetHelp(New(PBreakViewer, Init(R, 1, nil, Control)),
    hcBreakpointList));
  Insert(Viewer);
  R.Assign(2, 2, 69, 3);
  Insert(New(PLabel, Init(R,
    '~B~reakpoint list         Line # Condition                      Pass',
    Viewer)));
  Insert(OkButton(2, 12));
  Insert(NewButton(13, 12, 10, '~E~dit', cmEditBreakpoint, bfNormal,
    hcEditBreakpoint));
  Insert(NewButton(24, 12, 10, '~D~elete', cmDeleteBreakpoint, bfNormal,
    hcDeleteBreakpoint));
  Insert(NewButton(35, 12, 10, '~V~iew', cmViewBreakpoint, bfNormal,
    hcViewBreakpoint));
  Insert(NewButton(46, 12, 13, '~C~lear all', cmClearAllBreakpoints, bfNormal,
    hcClearAllBreakpoints));
  Insert(HelpButton(60, 12, hcBreakpointsDialog));
  SelectNext(False);
end;

constructor TBreakDialog.Load(var S: TStream);
begin
  TDialog.Load(S);
  GetSubViewPtr(S, Viewer);
end;

procedure TBreakDialog.HandleEvent(var Event: TEvent);
var
  E: TEvent;
begin
  TDialog.HandleEvent(Event);
  case Event.What of
    evCommand:
      case Event.Command of
        cmEditBreakpoint:
          begin
            Viewer^.Edit;
            ClearEvent(Event)
          end;
        cmDeleteBreakpoint:
          begin
            Viewer^.Delete;
            Viewer^.select;
            ClearEvent(Event);
          end;
        cmViewBreakpoint:
          if Viewer^.Focused < BptCount then
          begin
            EndModal(cmViewBreakpoint);
            E.What := evCommand;
            E.Command := cmShowBreakpoint;
            E.InfoInt := Viewer^.Focused;
            PutEvent(E);
            ClearEvent(Event);
          end;
        cmHackBreakpoint:
          ;
        cmClearAllBreakpoints:
          begin
            Viewer^.ClearAll;
            Viewer^.select;
            ClearEvent(Event);
          end;
      end;
  end;
end;

procedure TBreakDialog.Store(var S: TStream);
begin
  TDialog.Store(S);
  PutSubViewPtr(S, Viewer);
end;

constructor TEditBreakDialog.Init;
var
  R: TRect;
  Control: PView;
begin
  R.Assign(15, 4, 65, 19);
  TDialog.Init(R, 'Edit Breakpoint');
  Options := Options or ofCentered;
  R.Assign(3, 3, 33, 4);
  Control := SetHelp(New(PInputLine, Init(R, 79)), hcCondition);
  Insert(Control);
  Insert(StandardHistory(PInputLine(Control), hlCondition));
  Insert(StandardLabel('~C~ondition', Control, lfTop));
  R.Move(0, 3);
  Control := SetHelp(New(PIntField, Init(R, 5, 0, 32767)), hcPassCount);
  Insert(Control);
  Insert(StandardLabel('~P~ass count', Control, lfTop));
  R.Move(0, 3);
  Control := SetHelp(New(PInputLine, Init(R, 79)), hcFileName);
  Insert(Control);
  Insert(StandardLabel('~F~ile name', Control, lfTop));
  R.Move(0, 3);
  Control := SetHelp(New(PIntField, Init(R, 5, 1, 32767)), hcLineNumber);
  Insert(Control);
  Insert(StandardLabel('~L~ine number', Control, lfTop));
  Insert(NewButton(37, 3, 10, '~M~odify', cmModifyBreakpoint, bfDefault,
    hcModifyBreakpointButton));
  Insert(NewButton(37, 6, 10, '~N~ew', cmNewBreakpoint, bfNormal,
    hcNewBreakpointButton));
  Insert(CnlButton(37, 9));
  Insert(HelpButton(37, 12, hcEditBreakpointDialog));
  SelectNext(False);
end;

procedure TEditBreakDialog.HandleEvent(var Event: TEvent);
begin
  TDialog.HandleEvent(Event);
  if Event.What = evCommand then
    case Event.Command of
      cmModifyBreakpoint, cmNewBreakpoint:
        begin
          EndModal(Event.Command);
          ClearEvent(Event)
        end;
    end;
end;

end.
