Browse Source

+ First implementation of watches window

pierre 26 years ago
parent
commit
5f258b0fc0
9 changed files with 669 additions and 57 deletions
  1. 6 1
      ide/text/fp.pas
  2. 6 1
      ide/text/fpconst.pas
  3. 597 45
      ide/text/fpdebug.pas
  4. 6 2
      ide/text/fphelp.pas
  5. 9 3
      ide/text/fpide.pas
  6. 35 2
      ide/text/fpmdebug.inc
  7. 5 1
      ide/text/fpmwnd.inc
  8. 5 1
      ide/text/fpvars.pas
  9. 0 1
      ide/text/test.pas

+ 6 - 1
ide/text/fp.pas

@@ -135,6 +135,7 @@ BEGIN
   InitRedir;
 {$ifndef NODEBUG}
   InitBreakpoints;
+  InitWatches;
 {$endif}
   InitReservedWords;
   InitHelpFiles;
@@ -188,13 +189,17 @@ BEGIN
 {$ifndef NODEBUG}
   DoneDebugger;
   DoneBreakpoints;
+  DoneWatches;
 {$endif}
 
   StreamError:=nil;
 END.
 {
   $Log$
-  Revision 1.27  1999-06-29 22:43:12  peter
+  Revision 1.28  1999-07-10 01:24:11  pierre
+   + First implementation of watches window
+
+  Revision 1.27  1999/06/29 22:43:12  peter
     * try to add extensions to params
 
   Revision 1.26  1999/06/28 23:31:14  pierre

+ 6 - 1
ide/text/fpconst.pas

@@ -118,6 +118,7 @@ const
      cmSymbol            = 235;
      cmStack             = 236;
      cmBreakpointList    = 237;
+     cmWatches           = 238;
 
      cmNotImplemented    = 1000;
      cmNewFromTemplate   = 1001;
@@ -280,6 +281,7 @@ const
      hcToggleBreakpoint  = hcShift+cmToggleBreakpoint;
      hcEvaluate          = hcShift+cmEvaluate;
      hcAddWatch          = hcShift+cmAddWatch;
+     hcWatches           = hcShift+cmWatches;
      hcGrep              = hcShift+cmGrep;
      hcStack             = hcShift+cmStack;
      hcBreakPointList    = hcShift+cmBreakpointList;
@@ -333,7 +335,10 @@ implementation
 END.
 {
   $Log$
-  Revision 1.20  1999-06-30 23:58:11  pierre
+  Revision 1.21  1999-07-10 01:24:13  pierre
+   + First implementation of watches window
+
+  Revision 1.20  1999/06/30 23:58:11  pierre
     + BreakpointsList Window implemented
       with Edit/New/Delete functions
     + Individual breakpoint dialog with support for all types

+ 597 - 45
ide/text/fpdebug.pas

@@ -38,6 +38,7 @@ type
     procedure AnnotateError;
     procedure InsertBreakpoints;
     procedure RemoveBreakpoints;
+    procedure ReadWatches;
     procedure ResetBreakpointsValues;
     procedure DoDebuggerScreen;virtual;
     procedure DoUserScreen;virtual;
@@ -132,8 +133,8 @@ type
       procedure   HandleEvent(var Event: TEvent); virtual;
       procedure   Update; virtual;
       destructor  Done; virtual;
-    end;                                                                                                                                                                                                                                                       
-                                                                                                                                                                                                                                                               
+    end;
+
     PBreakpointItemDialog = ^TBreakpointItemDialog;
 
     TBreakpointItemDialog = object(TCenterDialog)
@@ -148,6 +149,68 @@ type
       IgnoreIL  : PInputLine;
     end;
 
+    PWatch = ^TWatch;
+    TWatch =  Object(TObject)
+      constructor Init(s : string);
+      procedure rename(s : string);
+      procedure Get_new_value;
+      destructor done;virtual;
+    private
+      expr : pstring;
+      last_value,current_value : pchar;
+    end;
+
+    PWatchesCollection = ^TWatchesCollection;
+    TWatchesCollection = Object(TCollection)
+      constructor Init;
+      procedure Insert(Item: Pointer); virtual;
+      function  At(Index: Integer): PWatch;
+      procedure Update;
+    private
+      MaxW : integer;
+    end;
+
+    PWatchesListBox = ^TWatchesListBox;
+    TWatchesListBox = object(THSListBox)
+      Transparent : boolean;
+      MaxWidth    : Sw_integer;
+      constructor Init(var Bounds: TRect; AHScrollBar, AVScrollBar: PScrollBar);
+      (* procedure   AddWatch(P: PWatch); virtual; *)
+      procedure   Update(AMaxWidth : integer);
+      function    GetIndentedText(Item,Indent,MaxLen: Sw_Integer): String; virtual;
+      function    GetLocalMenu: PMenu;virtual;
+      (* procedure   Clear; virtual;
+      procedure   TrackSource; virtual;*)
+      procedure   EditNew; virtual;
+      procedure   EditCurrent; virtual;
+      procedure   DeleteCurrent; virtual;
+      (*procedure   ToggleCurrent; *)
+      procedure   Draw; virtual;
+      procedure   HandleEvent(var Event: TEvent); virtual;
+      (* constructor Load(var S: TStream);
+      procedure   Store(var S: TStream); *)
+      destructor  Done; virtual;
+    end;
+
+    PWatchItemDialog = ^TWatchItemDialog;
+
+    TWatchItemDialog = object(TCenterDialog)
+      constructor Init(AWatch: PWatch);
+      function    Execute: Word; virtual;
+    private
+      Watch : PWatch;
+      NameIL  : PInputLine;
+      TextST : PAdvancedStaticText;
+    end;
+
+    PWatchesWindow = ^TWatchesWindow;
+    TWatchesWindow = Object(TDlgWindow)
+      WLB : PWatchesListBox;
+      Constructor Init;
+      procedure Update; virtual;
+      destructor  Done; virtual;
+    end;
+
 const
      BreakpointTypeStr : Array[BreakpointType] of String[9]
        = ( 'function','file-line','watch','awatch','rwatch','invalid' );
@@ -157,6 +220,7 @@ const
 var
   Debugger             : PDebugController;
   BreakpointCollection : PBreakpointCollection;
+  WatchesCollection    : PwatchesCollection;
 
 procedure InitDebugger;
 procedure DoneDebugger;
@@ -164,6 +228,8 @@ procedure InitGDBWindow;
 procedure DoneGDBWindow;
 procedure InitBreakpoints;
 procedure DoneBreakpoints;
+procedure InitWatches;
+procedure DoneWatches;                                                                                                                                                                                                                                         
 
 implementation
 
@@ -188,6 +254,7 @@ begin
   SetArgs(GetRunParameters);
   Debugger:=@self;
   InsertBreakpoints;
+  ReadWatches;
 end;
 
 procedure TDebugController.InsertBreakpoints;
@@ -200,6 +267,16 @@ begin
   BreakpointCollection^.ForEach(@DoInsert);
 end;
 
+procedure TDebugController.ReadWatches;
+  procedure DoRead(PB : PWatch);
+  begin
+    PB^.Get_new_value;
+  end;
+
+begin
+  WatchesCollection^.ForEach(@DoRead);
+end;
+
 
 procedure TDebugController.RemoveBreakpoints;
   procedure DoDelete(PB : PBreakpoint);
@@ -259,7 +336,7 @@ procedure TDebugController.CommandEnd(const s:string);
 begin
   if assigned(GDBWindow) and (in_command=0) then
     begin
-      { We should do somethnig special for errors !! }
+      { We should do something special for errors !! }
       If StrLen(GetError)>0 then
         GDBWindow^.WriteErrorText(GetError);
       GDBWindow^.WriteOutputText(GetOutput);
@@ -300,6 +377,7 @@ var
 begin
   BreakIndex:=stop_breakpoint_number;
   Desktop^.Lock;
+  { 0 based line count in Editor }
   if Line>0 then
     dec(Line);
   if (fn=LastFileName) then
@@ -310,6 +388,7 @@ begin
           W^.Editor^.SetCurPtr(0,Line);
           W^.Editor^.TrackCursor(true);
           W^.Editor^.SetHighlightRow(Line);
+          ReadWatches;
           if Not assigned(GDBWindow) or not GDBWindow^.GetState(sfActive) then
             W^.Select;
           InvalidSourceLine:=false;
@@ -324,6 +403,7 @@ begin
         begin
           W^.Editor^.SetHighlightRow(Line);
           W^.Editor^.TrackCursor(true);
+          ReadWatches;
           if Not assigned(GDBWindow) or not GDBWindow^.GetState(sfActive) then
             W^.Select;
           LastSource:=W;
@@ -346,6 +426,7 @@ begin
               W:=TryToOpenFile(nil,fn,0,Line,true);
               W^.Editor^.SetHighlightRow(Line);
               W^.Editor^.TrackCursor(true);
+              ReadWatches;
               if Not assigned(GDBWindow) or not GDBWindow^.GetState(sfActive) then
                 W^.Select;
               LastSource:=W;
@@ -357,7 +438,7 @@ begin
   Desktop^.UnLock;
   if BreakIndex>0 then
     begin
-      PB:=BreakpointCollection^.GetGDB(stop_breakpoint_number);
+      PB:=BreakpointCollection^.GetGDB(BreakIndex);
       { For watch we should get old and new value !! }
       if (Not assigned(GDBWindow) or not GDBWindow^.GetState(sfActive)) and
          (PB^.typ<>bt_file_line) and (PB^.typ<>bt_function) then
@@ -420,7 +501,6 @@ begin
   MyApp.ShowUserScreen;
 end;
 
-
 {****************************************************************************
                                  TBreakpoint
 ****************************************************************************}
@@ -733,11 +813,10 @@ end;
 
 constructor TBreakpointListBox.Init(var Bounds: TRect; AHScrollBar, AVScrollBar: PScrollBar);
 begin
-  inherited Init(Bounds,1,AHScrollBar, AVScrollBar);                                                                                                                                                                                                           
-  GrowMode:=gfGrowLoX+gfGrowHiX+gfGrowHiY;                                                                                                                                                                                                                     
-  (* New(ModuleNames, Init(50,100)); *)
-  NoSelection:=true;                                                                                                                                                                                                                                           
-end;                                                                                                                                                                                                                                                           
+  inherited Init(Bounds,1,AHScrollBar, AVScrollBar);
+  GrowMode:=gfGrowLoX+gfGrowHiX+gfGrowHiY;
+  NoSelection:=true;
+end;
 
 function TBreakpointListBox.GetLocalMenu: PMenu;
 var M: PMenu;
@@ -798,7 +877,7 @@ begin
         if not DontClear then
           ClearEvent(Event);
       end;
-  end;                                                                                                                                                                                                                                                         
+  end;
   inherited HandleEvent(Event);
 end;
 
@@ -808,18 +887,18 @@ begin
   if List=nil then New(List, Init(20,20));
   W:=length(P^.GetText(255));
   if W>MaxWidth then
-  begin                                                                                                                                                                                                                                                        
-    MaxWidth:=W;                                                                                                                                                                                                                                               
+  begin
+    MaxWidth:=W;
     if HScrollBar<>nil then
-       HScrollBar^.SetRange(0,MaxWidth);                                                                                                                                                                                                                       
+       HScrollBar^.SetRange(0,MaxWidth);
   end;
   List^.Insert(P);
   SetRange(List^.Count);
   if Focused=List^.Count-1-1 then
      FocusItem(List^.Count-1);
   DrawView;
-end;                                                                                                                                                                                                                                                           
-                                                                                                                                                                                                                                                               
+end;
+
 (* function TBreakpointListBox.AddModuleName(const Name: string): PString;
 var P: PString;                                                                                                                                                                                                                                                
 begin
@@ -829,7 +908,7 @@ begin
     P:=nil;                                                                                                                                                                                                                                                    
   AddModuleName:=P;
 end;  *)
-                                                                                                                                                                                                                                                               
+
 function TBreakpointListBox.GetText(Item,MaxLen: Sw_Integer): String;
 var P: PBreakpointItem;
     S: string;                                                                                                                                                                                                                                                 
@@ -841,7 +920,7 @@ end;
                                                                                                                                                                                                                                                                
 procedure TBreakpointListBox.Clear;
 begin                                                                                                                                                                                                                                                          
-  if assigned(List) then                                                                                                                                                                                                                                       
+  if assigned(List) then
     Dispose(List, Done);
   List:=nil;
   MaxWidth:=0;
@@ -850,12 +929,12 @@ begin
   SetRange(0); DrawView;
   Message(Application,evBroadcast,cmClearLineHighlights,@Self);
 end;
-                                                                                                                                                                                                                                                               
+
 procedure TBreakpointListBox.TrackSource;
 var W: PSourceWindow;
     P: PBreakpointItem;
     R: TRect;
-    Row,Col: sw_integer;
+    (* Row,Col: sw_integer; *)
 begin
   (*Message(Application,evBroadcast,cmClearLineHighlights,@Self);
   if Range=0 then Exit;*)
@@ -889,7 +968,7 @@ procedure TBreakpointListBox.ToggleCurrent;
 var W: PSourceWindow;
     P: PBreakpointItem;
     b : boolean;
-    Row,Col: sw_integer;
+    (* Row,Col: sw_integer; *)
 begin
   if Range=0 then Exit;
   P:=List^.At(Focused);
@@ -914,9 +993,8 @@ begin
 end;
 
 procedure TBreakpointListBox.EditCurrent;
-var W: PSourceWindow;
-    P: PBreakpointItem;
-    Row,Col: sw_integer;
+var
+  P: PBreakpointItem;
 begin
   if Range=0 then Exit;
   P:=List^.At(Focused);
@@ -926,9 +1004,8 @@ begin
 end;
 
 procedure TBreakpointListBox.DeleteCurrent;
-var W: PSourceWindow;
-    P: PBreakpointItem;
-    Row,Col: sw_integer;
+var
+  P: PBreakpointItem;
 begin
   if Range=0 then Exit;
   P:=List^.At(Focused);
@@ -939,9 +1016,8 @@ begin
 end;
 
 procedure TBreakpointListBox.EditNew;
-var W: PSourceWindow;
-    P: PBreakpoint;
-    Row,Col: sw_integer;
+var
+  P: PBreakpoint;
 begin
   P:=New(PBreakpoint,Init_Empty);
   if Application^.ExecuteDialog(New(PBreakpointItemDialog,Init(P)),nil)<>cmCancel then
@@ -952,7 +1028,7 @@ begin
   else
     dispose(P,Done);
 end;
-                                                                                                                                                                                                                                                               
+
 procedure TBreakpointListBox.Draw;
 var
   I, J, Item: Sw_Integer;
@@ -967,36 +1043,36 @@ begin
   if (Owner<>nil) then TC:=ord(Owner^.GetColor(6)) else TC:=0;
   if State and (sfSelected + sfActive) = (sfSelected + sfActive) then
   begin                                                                                                                                                                                                                                                        
-    NormalColor := GetColor(1);                                                                                                                                                                                                                                
+    NormalColor := GetColor(1);
     FocusedColor := GetColor(3);
     SelectedColor := GetColor(4);
   end else
   begin
     NormalColor := GetColor(2);
-    SelectedColor := GetColor(4);                                                                                                                                                                                                                              
+    SelectedColor := GetColor(4);
   end;
-  if Transparent then                                                                                                                                                                                                                                          
+  if Transparent then
     begin MT(NormalColor); MT(SelectedColor); end;                                                                                                                                                                                                             
-  if NoSelection then                                                                                                                                                                                                                                          
+  if NoSelection then
      SelectedColor:=NormalColor;
   if HScrollBar <> nil then Indent := HScrollBar^.Value
   else Indent := 0;
   ColWidth := Size.X div NumCols + 1;                                                                                                                                                                                                                          
   for I := 0 to Size.Y - 1 do                                                                                                                                                                                                                                  
   begin
-    for J := 0 to NumCols-1 do                                                                                                                                                                                                                                 
+    for J := 0 to NumCols-1 do
     begin
       Item := J*Size.Y + I + TopItem;
-      CurCol := J*ColWidth;                                                                                                                                                                                                                                    
+      CurCol := J*ColWidth;
       if (State and (sfSelected + sfActive) = (sfSelected + sfActive)) and                                                                                                                                                                                     
         (Focused = Item) and (Range > 0) then
       begin
         Color := FocusedColor;
         SetCursor(CurCol+1,I);
         SCOff := 0;
-      end                                                                                                                                                                                                                                                      
+      end
       else if (Item < Range) and IsSelected(Item) then
-      begin                                                                                                                                                                                                                                                    
+      begin
         Color := SelectedColor;                                                                                                                                                                                                                                
         SCOff := 2;                                                                                                                                                                                                                                            
       end
@@ -1004,7 +1080,7 @@ begin
       begin                                                                                                                                                                                                                                                    
         Color := NormalColor;                                                                                                                                                                                                                                  
         SCOff := 4;
-      end;                                                                                                                                                                                                                                                     
+      end;
       MoveChar(B[CurCol], ' ', Color, ColWidth);                                                                                                                                                                                                               
       if Item < Range then
       begin
@@ -1060,9 +1136,7 @@ var R,R2: TRect;
     HSB,VSB: PScrollBar;
     ST: PStaticText;
     S: String;
-    W,H : Sw_integer;
-    X   : Sw_integer;
-    X1,X2,X3: Sw_integer;
+    X,X1 : Sw_integer;
 const White = 15;
 begin
   Desktop^.GetExtent(R); R.A.Y:=R.B.Y-18;
@@ -1104,7 +1178,7 @@ begin
   X1:=X1+X;
   R.A.X:=X1-3;R.B.X:=X1+7;
   Insert(New(PButton, Init(R, '~D~elete', cmDelete, bfNormal)));
-  BreakLB^.Select;                                                                                                                                                                                                                                  
+  BreakLB^.Select;
   Update;
   BreakpointsWindow:=@self;
 end;
@@ -1294,6 +1368,470 @@ begin
   Execute:=R;
 end;
 
+{****************************************************************************
+                         TWatch
+****************************************************************************}
+
+      constructor TWatch.Init(s : string);
+        begin
+          expr:=NewStr(s);
+          last_value:=nil;
+          current_value:=nil;
+          Get_new_value;
+        end;
+
+      procedure TWatch.rename(s : string);
+        begin
+          if assigned(expr) then
+            begin
+              if GetStr(expr)=S then
+                exit;
+              DisposeStr(expr);
+            end;
+          expr:=NewStr(s);
+          if assigned(last_value) then
+            StrDispose(last_value);
+          last_value:=nil;
+          if assigned(current_value) then
+            StrDispose(current_value);
+          current_value:=nil;
+          Get_new_value;
+        end;
+
+      procedure TWatch.Get_new_value;
+        var p,q : pchar;
+            i : longint;
+            last_removed : boolean;
+        begin
+          If not assigned(Debugger) then
+            exit;
+          if assigned(last_value) then
+            strdispose(last_value);
+          last_value:=current_value;
+          Debugger^.Command('p '+GetStr(expr));
+          p:=strnew(Debugger^.GetOutput);
+          if assigned(p) and (p[0]='$') then
+            q:=StrPos(p,'=');
+          if not assigned(q) then
+            q:=p;
+          i:=strlen(q);
+          if q[i-1]=#10 then
+            begin
+              q[i-1]:=#0;
+              last_removed:=true;
+            end
+          else
+            last_removed:=false;
+          current_value:=strnew(q);
+          if last_removed then
+            q[i-1]:=#10;
+          strdispose(p);
+        end;
+
+      destructor TWatch.Done;
+        begin
+          if assigned(expr) then
+            disposestr(expr);
+          if assigned(last_value) then
+            strdispose(last_value);
+          if assigned(current_value) then
+            strdispose(current_value);
+          inherited done;
+        end;
+
+{****************************************************************************
+                         TWatchesCollection
+****************************************************************************}
+
+      constructor TWatchesCollection.Init;
+        begin
+          inherited Init(10,10);
+        end;
+
+      procedure TWatchesCollection.Insert(Item: Pointer);
+       begin
+         PWatch(Item)^.Get_new_value;
+         Inherited Insert(Item);
+         Update;
+       end;
+
+      procedure TWatchesCollection.Update;
+        var
+         W,W1 : integer;
+         procedure GetMax(P : PWatch);
+           begin
+              if assigned(P^.Current_value) then
+               begin
+                 W1:=StrLen(P^.Current_value)+2+Length(GetStr(P^.expr));
+                 if W1>W then
+                  W:=W1;
+               end;
+           end;
+        begin
+          W:=0;
+          ForEach(@GetMax);
+          MaxW:=W;
+          If assigned(WatchesWindow) then
+            WatchesWindow^.WLB^.Update(MaxW);
+        end;
+
+      function  TWatchesCollection.At(Index: Integer): PWatch;
+        begin
+          At:=Inherited At(Index);
+        end;
+
+{****************************************************************************
+                         TWatchesListBox
+****************************************************************************}
+
+    (* PWatchesListBox = ^TWatchesListBox;
+    TWatchesListBox = object(THSListBox)
+      MaxWidth    : Sw_integer; *)
+constructor TWatchesListBox.Init(var Bounds: TRect; AHScrollBar, AVScrollBar: PScrollBar);
+  begin
+    inherited Init(Bounds,1,AHScrollBar,AVScrollBar);
+    If assigned(List) then
+      dispose(list,done);
+    List:=WatchesCollection;
+  end;
+
+procedure TWatchesListBox.Update(AMaxWidth : integer);
+begin
+  MaxWidth:=AMaxWidth;
+  if HScrollBar<>nil then
+    HScrollBar^.SetRange(0,MaxWidth);
+  SetRange(List^.Count);
+  if Focused=List^.Count-1-1 then
+     FocusItem(List^.Count-1);
+  DrawView;
+end;
+
+function    TWatchesListBox.GetIndentedText(Item,Indent,MaxLen: Sw_Integer): String;
+var
+  PW : PWatch;
+  ValOffset : Sw_integer;
+  S : String;
+begin
+  PW:=WatchesCollection^.At(Item);
+  ValOffset:=Length(GetStr(PW^.Expr))+2;
+  if Indent<ValOffset then
+    begin
+      if not assigned(PW^.current_value) then
+        S:=' '+GetStr(PW^.Expr)+' <Unknown value>'
+      else if not assigned(PW^.last_value) or
+        (strcomp(PW^.Last_value,PW^.Current_value)=0) then
+        S:=' '+GetStr(PW^.Expr)+' '+StrPas(PW^.Current_value)
+      else
+        S:='!'+GetStr(PW^.Expr)+'!'+StrPas(PW^.Current_value);
+      GetIndentedText:=Copy(S,Indent,MaxLen);
+    end
+  else
+   begin
+      if not assigned(PW^.Current_value) or
+         (StrLen(PW^.Current_value)<Indent-Valoffset) then
+        S:=''
+      else
+        S:=StrPas(@(PW^.Current_Value[Indent-Valoffset]));
+      GetIndentedText:=Copy(S,1,MaxLen);
+   end;
+end;
+
+      (* function    TWatchesListBox.GetLocalMenu: PMenu;virtual;
+      procedure   TWatchesListBox.Clear; virtual;
+      procedure   TWatchesListBox.TrackSource; virtual;
+      procedure   TWatchesListBox.EditNew; virtual;
+      procedure   TWatchesListBox.EditCurrent; virtual;
+      procedure   TWatchesListBox.DeleteCurrent; virtual;
+      procedure   TWatchesListBox.ToggleCurrent; *)
+
+procedure TWatchesListBox.EditCurrent;
+var
+  P: PWatch;
+begin
+  if Range=0 then Exit;
+  P:=WatchesCollection^.At(Focused);
+  if P=nil then Exit;
+  Application^.ExecuteDialog(New(PWatchItemDialog,Init(P)),nil);
+  WatchesCollection^.Update;
+end;
+
+procedure TWatchesListBox.DeleteCurrent;
+var
+  P: PWatch;
+begin
+  if Range=0 then Exit;
+  P:=WatchesCollection^.At(Focused);
+  if P=nil then Exit;
+  WatchesCollection^.free(P);
+  WatchesCollection^.Update;
+end;
+
+procedure TWatchesListBox.EditNew;
+var
+  P: PWatch;
+begin
+  P:=New(PWatch,Init(''));
+  if Application^.ExecuteDialog(New(PWatchItemDialog,Init(P)),nil)<>cmCancel then
+    begin
+      WatchesCollection^.Insert(P);
+      WatchesCollection^.Update;
+    end
+  else
+    dispose(P,Done);
+end;
+
+procedure   TWatchesListBox.Draw;
+var
+  I, J, Item: Sw_Integer;
+  NormalColor, SelectedColor, FocusedColor, Color: Word;
+  ColWidth, CurCol, Indent: Integer;
+  B: TDrawBuffer;
+  Text: String;
+  SCOff: Byte;
+  TC: byte;
+procedure MT(var C: word); begin if TC<>0 then C:=(C and $ff0f) or (TC and $f0); end;
+begin
+  if (Owner<>nil) then TC:=ord(Owner^.GetColor(6)) else TC:=0;
+  if State and (sfSelected + sfActive) = (sfSelected + sfActive) then
+  begin
+    NormalColor := GetColor(1);
+    FocusedColor := GetColor(3);
+    SelectedColor := GetColor(4);
+  end else
+  begin
+    NormalColor := GetColor(2);
+    SelectedColor := GetColor(4);
+  end;
+  if Transparent then
+    begin MT(NormalColor); MT(SelectedColor); end;
+  (* if NoSelection then
+     SelectedColor:=NormalColor;*)
+  if HScrollBar <> nil then Indent := HScrollBar^.Value
+  else Indent := 0;
+  ColWidth := Size.X div NumCols + 1;
+  for I := 0 to Size.Y - 1 do
+  begin
+    for J := 0 to NumCols-1 do
+    begin
+      Item := J*Size.Y + I + TopItem;
+      CurCol := J*ColWidth;
+      if (State and (sfSelected + sfActive) = (sfSelected + sfActive)) and
+        (Focused = Item) and (Range > 0) then
+      begin
+        Color := FocusedColor;
+        SetCursor(CurCol+1,I);
+        SCOff := 0;
+      end
+      else if (Item < Range) and IsSelected(Item) then
+      begin
+        Color := SelectedColor;
+        SCOff := 2;
+      end
+      else
+      begin
+        Color := NormalColor;
+        SCOff := 4;
+      end;
+      MoveChar(B[CurCol], ' ', Color, ColWidth);
+      if Item < Range then
+      begin
+        (* Text := GetText(Item, ColWidth + Indent);
+        Text := Copy(Text,Indent,ColWidth); *)
+        Text:=GetIndentedText(Item,Indent,ColWidth);
+        MoveStr(B[CurCol+1], Text, Color);
+        if ShowMarkers then
+        begin
+          WordRec(B[CurCol]).Lo := Byte(SpecialChars[SCOff]);
+          WordRec(B[CurCol+ColWidth-2]).Lo := Byte(SpecialChars[SCOff+1]);
+        end;
+      end;
+      MoveChar(B[CurCol+ColWidth-1], #179, GetColor(5), 1);
+    end;
+    WriteLine(0, I, Size.X, 1, B);
+  end;
+end;
+
+function TWatchesListBox.GetLocalMenu: PMenu;
+var M: PMenu;
+begin
+  if (Owner<>nil) and (Owner^.GetState(sfModal)) then M:=nil else
+  M:=NewMenu(
+    NewItem('~E~dit watch','',kbNoKey,cmEdit,hcNoContext,
+    NewItem('~N~ew watch','',kbNoKey,cmNew,hcNoContext,
+    NewItem('~D~elete watch','',kbNoKey,cmDelete,hcNoContext,
+    nil))));
+  GetLocalMenu:=M;
+end;
+
+procedure   TWatchesListBox.HandleEvent(var Event: TEvent);
+var DontClear: boolean;
+begin
+  case Event.What of
+    evKeyDown :
+      begin
+        DontClear:=false;
+        case Event.KeyCode of
+          kbEnter :
+            Message(@Self,evCommand,cmEdit,nil);
+          kbIns :
+            Message(@Self,evCommand,cmNew,nil);
+          kbDel :
+            Message(@Self,evCommand,cmDelete,nil);
+        else
+          DontClear:=true;
+        end;
+        if not DontClear then
+          ClearEvent(Event);
+      end;
+    evBroadcast :
+      case Event.Command of
+        cmListItemSelected :
+          if Event.InfoPtr=@Self then
+            Message(@Self,evCommand,cmEdit,nil);
+      end;
+    evCommand :
+      begin
+        DontClear:=false;
+        case Event.Command of
+          cmEdit :
+              EditCurrent;
+          cmDelete :
+              DeleteCurrent;
+          cmNew :
+              EditNew;
+          else
+            DontClear:=true;
+        end;
+        if not DontClear then
+          ClearEvent(Event);
+      end;
+  end;
+  inherited HandleEvent(Event);
+end;                                                                                                                                                                                                                                                           
+                                                                                                                                                                                                                                                               
+      (* constructor TWatchesListBox.Load(var S: TStream);
+      procedure   TWatchesListBox.Store(var S: TStream); *)
+      destructor  TWatchesListBox.Done;
+        begin
+          List:=nil;
+          inherited Done;
+        end;
+
+{****************************************************************************
+                         TWatchesWindow
+****************************************************************************}
+
+  Constructor TWatchesWindow.Init;
+    var
+      R : trect;
+    begin
+      Desktop^.GetExtent(R);
+      R.A.Y:=R.B.Y-5;
+      inherited Init(R, 'Watches', wnNoNumber);
+      GetExtent(R);
+      HelpCtx:=hcWatches;
+      R.Grow(-1,-1);
+      New(WLB,Init(R,nil,nil));
+      WLB^.GrowMode:=gfGrowHiX+gfGrowHiY;
+      WLB^.Transparent:=true;
+      Insert(WLB);
+      If assigned(WatchesWindow) then
+        dispose(WatchesWindow,done);
+      WatchesWindow:=@Self;
+    end;
+
+  procedure TWatchesWindow.Update;
+    begin
+      WatchesCollection^.Update;
+      Draw;
+    end;
+
+  Destructor TWatchesWindow.Done;
+    begin
+      WatchesWindow:=nil;
+      Dispose(WLB,done);
+      inherited done;
+    end;
+    
+
+{****************************************************************************
+                         TWatchItemDialog
+****************************************************************************}
+    (* TWatchItemDialog = object(TCenterDialog)
+      constructor Init(AWatch: PWatch);
+      function    Execute: Word; virtual;
+    private
+      Watch : PWatch;
+      NameIL  : PInputLine;
+      TextST : PAdvancedStaticText;
+      CurrentIL: PLabel;
+      LastIL    : PLabel;
+    end;  *)
+
+constructor TWatchItemDialog.Init(AWatch: PWatch);
+var R,R2: TRect;
+begin
+  R.Assign(0,0,50,10);
+  inherited Init(R,'Edit Watch');
+  Watch:=AWatch;
+
+  GetExtent(R); R.Grow(-3,-2);
+  Inc(R.A.Y); R.B.Y:=R.A.Y+1; R.B.X:=R.A.X+36;
+  New(NameIL, Init(R, 255)); Insert(NameIL);
+  R2.Copy(R); R2.Move(-1,-1);
+  Insert(New(PLabel, Init(R2, '~E~xpression to watch', NameIL)));
+  GetExtent(R);
+  R.Grow(-1,-1);
+  R.A.Y:=R.A.Y+3;
+  R.B.X:=R.A.X+36;
+  TextST:=New(PAdvancedStaticText, Init(R, 'Watch values'));
+  Insert(TextST);
+
+  InsertButtons(@Self);
+
+  NameIL^.Select;
+end;
+
+function TWatchItemDialog.Execute: Word;
+var R: word;
+    S1,S2: string;
+    err: word;
+    L: longint;
+begin
+  S1:=GetStr(Watch^.expr);
+  NameIL^.SetData(S1);
+
+  if assigned(Watch^.Current_value) then
+    S1:=StrPas(Watch^.Current_value)
+  else
+    S1:='';
+
+  if assigned(Watch^.Last_value) then
+    S2:=StrPas(Watch^.Last_value)
+  else
+    S2:='';
+
+  if assigned(Watch^.Last_value) and
+     assigned(Watch^.Current_value) and
+     (strcomp(Watch^.Last_value,Watch^.Current_value)=0) then
+    S1:='Current value: '+#13+S1
+  else
+    S1:='Current value: '+#13+S1+#13+
+        'Previous value: '+#13+S2;
+
+  TextST^.SetText(S1);
+
+  R:=inherited Execute;
+  if R=cmOK then
+  begin
+    NameIL^.GetData(S1);
+    If assigned(Watch^.Expr) then
+          DisposeStr(Watch^.Expr);
+    Watch^.expr:=NewStr(S1);
+  end;
+  Execute:=R;
+end;
+
 {****************************************************************************
                          Init/Final
 ****************************************************************************}
@@ -1369,11 +1907,25 @@ begin
   BreakpointCollection:=nil;
 end;
 
+procedure InitWatches;
+begin
+  New(WatchesCollection,init);
+end;
+
+procedure DoneWatches;
+begin
+  Dispose(WatchesCollection,Done);
+  WatchesCollection:=nil;
+end;
+
 end.
 
 {
   $Log$
-  Revision 1.19  1999-06-30 23:58:12  pierre
+  Revision 1.20  1999-07-10 01:24:14  pierre
+   + First implementation of watches window
+
+  Revision 1.19  1999/06/30 23:58:12  pierre
     + BreakpointsList Window implemented
       with Edit/New/Delete functions
     + Individual breakpoint dialog with support for all types

+ 6 - 2
ide/text/fphelp.pas

@@ -150,7 +150,8 @@ begin
     hcDebugMenu     : S:='Debug Program';
     hcToggleBreakpoint : S:='Toggles Breakpoint';
     hcOpenGDBWindow : S:='Open direct window to GDB';
-    hcAddWatch      : S:='Add a new watch';
+    hcAddWatch      : S:='Add a new expression to watch';
+    hcWatches       : S:='Open the Watches Window';
     hcStack         : S:='Show calling stack';
     hcBreakpointList : S:='Edit breakpoints';
     hcToolsMenu     : S:='User installed tools';
@@ -385,7 +386,10 @@ end;
 END.
 {
   $Log$
-  Revision 1.17  1999-06-30 23:58:14  pierre
+  Revision 1.18  1999-07-10 01:24:16  pierre
+   + First implementation of watches window
+
+  Revision 1.17  1999/06/30 23:58:14  pierre
     + BreakpointsList Window implemented
       with Edit/New/Delete functions
     + Individual breakpoint dialog with support for all types

+ 9 - 3
ide/text/fpide.pas

@@ -70,6 +70,7 @@ type
       procedure DoToggleBreak;
       procedure DoShowCallStack;
       procedure DoShowBreakpointList;
+      procedure DoShowWatches;
       procedure DoAddWatch;
 
       procedure DoInformation;
@@ -249,11 +250,12 @@ begin
       NewItem('~U~ser screen','Alt+F5', kbAltF5, cmUserScreen, hcUserScreen,
       NewItem('~B~reakpoint','Ctrl+F8', kbCtrlF8, cmToggleBreakpoint, hcToggleBreakpoint,
       NewItem('~C~all stack','Ctrl+F3', kbCtrlF3, cmStack, hcStack,
-      NewItem('Add ~W~atch','', kbNoKey, cmAddWatch, hcAddWatch,
+      NewItem('~A~dd Watch','Ctrl+F7', kbCtrlF7, cmAddWatch, hcAddWatch,
+      NewItem('~W~atches','', kbNoKey, cmWatches, hcWatches,
       NewItem('Breakpoint ~L~ist','', kbNoKey, cmBreakpointList, hcBreakpointList,
       NewLine(
       NewItem('~G~DB window','', kbNoKey, cmOpenGDBWindow, hcOpenGDBWindow,
-      nil))))))))),
+      nil)))))))))),
     NewSubMenu('~T~ools', hcToolsMenu, NewMenu(
       NewItem('~M~essages', 'F11', kbF11, cmToolsMessages, hcToolsMessages,
       NewItem('Goto ~n~ext','Alt+F8', kbAltF8, cmToolsMsgNext, hcToolsMsgNext,
@@ -425,6 +427,7 @@ begin
              cmToggleBreakpoint : DoToggleBreak;
              cmStack         : DoShowCallStack;
              cmBreakpointList : DoShowBreakpointList;
+             cmWatches       :  DoShowWatches;
              cmAddWatch      :  DoAddWatch;
              cmOpenGDBWindow : DoOpenGDBWindow;
            { -- Options menu -- }
@@ -763,7 +766,10 @@ end;
 END.
 {
   $Log$
-  Revision 1.31  1999-06-29 22:50:14  peter
+  Revision 1.32  1999-07-10 01:24:17  pierre
+   + First implementation of watches window
+
+  Revision 1.31  1999/06/29 22:50:14  peter
     * more fixes from gabor
 
   Revision 1.30  1999/06/28 19:32:20  peter

+ 35 - 2
ide/text/fpmdebug.inc

@@ -61,14 +61,47 @@ begin
     end;
 end;
 
+procedure TIDEApp.DoShowWatches;
+begin
+  If assigned(WatchesWindow) then
+    begin
+      WatchesWindow^.Update;
+      WatchesWindow^.MakeFirst;
+    end
+  else
+    begin
+      New(WatchesWindow,Init);
+      Desktop^.Insert(WatchesWindow);
+    end;
+end;
+
 procedure TIDEApp.DoAddWatch;
+var
+  P: PWatch;
+  EditorWindow : PSourceWindow;
+  S : string;
 begin
-  NotImplemented;
+  EditorWindow:=FirstEditorWindow;
+  If assigned(EditorWindow) then
+    S:=LowerCaseStr(EditorWindow^.Editor^.GetCurrentWord)
+  else
+    S:='';
+  P:=New(PWatch,Init(S));
+  if ExecuteDialog(New(PWatchItemDialog,Init(P)),nil)<>cmCancel then
+    begin
+      WatchesCollection^.Insert(P);
+      WatchesCollection^.Update;
+    end
+  else
+    dispose(P,Done);
 end;
 
 {
   $Log$
-  Revision 1.5  1999-06-30 23:58:17  pierre
+  Revision 1.6  1999-07-10 01:24:19  pierre
+   + First implementation of watches window
+
+  Revision 1.5  1999/06/30 23:58:17  pierre
     + BreakpointsList Window implemented
       with Edit/New/Delete functions
     + Individual breakpoint dialog with support for all types

+ 5 - 1
ide/text/fpmwnd.inc

@@ -62,6 +62,7 @@ begin
     hcBrowserWindow: S:=PBrowserWindow(P)^.GetTitle(MaxLen);
     hcMessagesWindow:S:=PMessagesWindow(P)^.GetTitle(MaxLen);
     hcGDBWindow,
+    hcWatches,
     hcBreakpointListWindow :
       S:=PWindow(P)^.GetTitle(MaxLen);
   else S:='???? - '+PWindow(P)^.GetTitle(MaxLen);
@@ -159,7 +160,10 @@ end;
 
 {
   $Log$
-  Revision 1.10  1999-06-30 23:58:18  pierre
+  Revision 1.11  1999-07-10 01:24:20  pierre
+   + First implementation of watches window
+
+  Revision 1.10  1999/06/30 23:58:18  pierre
     + BreakpointsList Window implemented
       with Edit/New/Delete functions
     + Individual breakpoint dialog with support for all types

+ 5 - 1
ide/text/fpvars.pas

@@ -50,6 +50,7 @@ const ClipboardWindow  : PClipboardWindow = nil;
       ProgramInfoWindow: PProgramInfoWindow = nil;
       GDBWindow        : PGDBWindow = nil;
       BreakpointsWindow : PBreakpointsWindow = nil;
+      WatchesWindow    : PWatchesWindow = nil;
       UserScreenWindow : PScreenWindow = nil;
       HeapView         : PFPHeapView = nil;
       HelpFiles        : WUtils.PUnsortedStringCollection = nil;
@@ -82,7 +83,10 @@ implementation
 END.
 {
   $Log$
-  Revision 1.18  1999-06-30 23:58:19  pierre
+  Revision 1.19  1999-07-10 01:24:21  pierre
+   + First implementation of watches window
+
+  Revision 1.18  1999/06/30 23:58:19  pierre
     + BreakpointsList Window implemented
       with Edit/New/Delete functions
     + Individual breakpoint dialog with support for all types

+ 0 - 1
ide/text/test.pas

@@ -3,7 +3,6 @@ program                TestProgram;
 uses Test2;
 
 const A =  1234;
-      B =  $1234;
       C =  #1#2#3#4;
       ConstBool1 = true;
       ConstBool2 = boolean(5);