Browse Source

* More Undo/Redo stuff

pierre 26 years ago
parent
commit
a18114b7af
1 changed files with 103 additions and 64 deletions
  1. 103 64
      ide/text/weditor.pas

+ 103 - 64
ide/text/weditor.pas

@@ -185,6 +185,7 @@ type
 
     PEditorActionCollection = ^TEditorActionCollection;
     TEditorActionCollection = object(TCollection)
+      function At(Idx : sw_integer) : PEditorAction;
     end;
 {$else}
     PEditorAction = ^TEditorAction;
@@ -227,6 +228,8 @@ type
       TabSize    : integer;
       HighlightRow: sw_integer;
       DebuggerRow: sw_integer;
+      UndoList    : PEditorActionCollection;
+      RedoList    : PEditorActionCollection;
       constructor Init(var Bounds: TRect; AHScrollBar, AVScrollBar:
           PScrollBar; AIndicator: PIndicator; AbufSize:Sw_Word);
       procedure   SetFlags(AFlags: longint); virtual;
@@ -291,8 +294,6 @@ type
       LastLocalCmd: word;
       KeyState    : Integer;
       ErrorMessage: PString;
-      UndoList    : PEditorActionCollection;
-      RedoList    : PEditorActionCollection;
       Bookmarks   : array[0..9] of TEditorBookmark;
       LockFlag    : integer;
       DrawCalled  : boolean;
@@ -1747,7 +1748,7 @@ begin
   else
     begin
      CP:=0; RX:=0;
-     while (RX<=X) and (CP<length(S)) do
+     while (RX<=X) and (CP<=length(S)) do
       begin
         Inc(CP);
         if S[CP]=TAB then
@@ -2230,6 +2231,7 @@ begin
   Lock;
   SCP:=CurPos;
   HoldUndo:=StoreUndo;
+  StoreUndo:=false;
   if CurPos.Y<GetLineCount then S:=GetLineText(CurPos.Y) else S:='';
   if Overwrite=false then
   begin
@@ -2250,7 +2252,7 @@ begin
     SetCurPtr(Ind,CurPos.Y+1);
 {$ifdef Undo}
      StoreUndo:=HoldUndo;
-     Addaction(eaInsertLine,SCP,CurPos,'');
+     Addaction(eaInsertLine,SCP,CurPos,IndentStr);
      StoreUndo:=false;
 {$endif Undo}
     AdjustSelection(CurPos.X-SCP.X,CurPos.Y-SCP.Y);
@@ -2262,9 +2264,21 @@ begin
       Lines^.Insert(NewLine(IndentStr));
       AdjustSelection(0,1);
       LimitsChanged;
+{$ifdef Undo}
+      StoreUndo:=HoldUndo;
+      UpdateAttrs(CurPos.Y,attrAll);
+      SetCurPtr(Ind,CurPos.Y+1);
+      Addaction(eaInsertLine,SCP,CurPos,IndentStr);
+      StoreUndo:=false;
+{$endif Undo}
+    end
+    else
+    begin
+      UpdateAttrs(CurPos.Y,attrAll);
+      StoreUndo:=HoldUndo;
+      SetCurPtr(Ind,CurPos.Y+1);
+      StoreUndo:=false;
     end;
-    UpdateAttrs(CurPos.Y,attrAll);
-    SetCurPtr(Ind,CurPos.Y+1);
   end;
   DrawLines(CurPos.Y);
   StoreUndo:=HoldUndo;
@@ -2280,7 +2294,7 @@ end;
 procedure TCodeEditor.BackSpace;
 var S,PreS: string;
     OI,CI,CP,Y,TX: Sw_integer;
-    SCP: TPoint;
+    SCP,SC1 : TPoint;
     HoldUndo : Boolean;
 begin
   if IsReadOnly then Exit;
@@ -2294,7 +2308,11 @@ begin
       begin
         S:=GetLineText(CurPos.Y-1);
         SetLineText(CurPos.Y-1,S+GetLineText(CurPos.Y));
+        StoreUndo:=HoldUndo;
+        SC1.X:=Length(S);SC1.Y:=CurPOS.Y-1;
+        AddAction(eaInsertText,SC1,SC1,GetLineText(CurPos.Y));
         DeleteLine(CurPos.Y);
+        StoreUndo:=false;
         LimitsChanged;
         SetCurPtr(length(S),CurPos.Y-1);
       end;
@@ -2330,7 +2348,7 @@ begin
      SetCurPtr(CP,CurPos.Y);
 {$ifdef Undo}
      StoreUndo:=HoldUndo;
-     Addaction(eaDeleteText,SCP,CurPos,' ');
+     Addaction(eaDeleteText,SCP,CurPos,Copy(S,CI,OI-CI));
      StoreUndo:=false;
 {$endif Undo}
    end;
@@ -2357,7 +2375,10 @@ begin
      if CurPos.Y<GetLineCount-1 then
       begin
         SetLineText(CurPos.Y,S+GetLineText(CurPos.Y+1));
+        StoreUndo:=HoldUndo;
+        AddAction(eaInsertText,CurPos,CurPos,GetLineText(CurPos.Y+1));
         DeleteLine(CurPos.Y+1);
+        StoreUndo:=false;
         LimitsChanged;
         SDX:=0; SDY:=-1;
       end;
@@ -2449,17 +2470,30 @@ begin
 end;
 
 procedure TCodeEditor.DelLine;
+var
+  HoldUndo : boolean;
+  SP : TPoint;
 begin
   if IsReadOnly then Exit;
   Lock;
   if GetLineCount>0 then
   begin
+    SP:=CurPos;
     DeleteLine(CurPos.Y);
+    HoldUndo:=StoreUndo;
+    StoreUndo:=false;
     LimitsChanged;
     AdjustSelection(0,-1);
     SetCurPtr(0,CurPos.Y);
     UpdateAttrs(Max(0,CurPos.Y-1),attrAll);
     DrawLines(CurPos.Y);
+    If HoldUndo then
+      with UndoList^.At(UndoList^.count-1)^ do
+        begin
+          EndPos:=CurPos;
+          StartPos:=SP;
+        end;
+    StoreUndo:=HoldUndo;
     SetModified(true);
   end;
   Unlock;
@@ -2804,7 +2838,7 @@ begin
     end
   else
     begin
-      if Overwrite and (CI<length(S)) then
+      if Overwrite and (CI<=length(S)) then
         SetLineText(CurPos.Y,copy(S,1,CI-1)+SC+copy(S,CI+1,255))
       else
         SetLineText(CurPos.Y,copy(S,1,CI-1)+SC+copy(S,CI,255));
@@ -3002,15 +3036,15 @@ procedure TCodeEditor.Undo;
 {$ifdef Undo}
 var
   Temp,Idx : Longint;
-  SCP : Tpoint;
 {$endif Undo}
 begin
 {$ifdef Undo}
   StoreUndo := False;
+  Lock;
   if UndoList^.count > 0 then
   begin
     Idx:=UndoList^.count-1;
-    with PEditorAction(UndoList^.At(Idx))^ do
+    with UndoList^.At(Idx)^ do
     begin
       case action of
         eaMoveCursor :
@@ -3018,39 +3052,33 @@ begin
             { move cursor back to original position }
             SetCurPtr(startpos.x,startpos.y);
           end;
+        eaInsertText :
+          begin
+            SetCurPtr(StartPos.X,StartPos.Y);
+            for Temp := 1 to length(Text^) do
+              DelChar;
+          end;
+        eaDeleteText :
+          begin
+            { reinsert deleted text }
+            SetCurPtr(EndPos.X,EndPos.Y);
+            for Temp := 1 to length(Text^) do
+              AddChar(Text^[Temp]);
+            SetCurPtr(StartPos.X,StartPos.Y);
+          end;
         eaInsertLine :
           begin
-            { move cursor to inserted line, already done by other undo action?}
-            { delete inserted line}
-            { move cursor to end of line above }
-            { insert text that had been moved to line below }
             SetCurPtr(EndPos.X,EndPos.Y);
             SetDisplayText(EndPos.Y,Copy(GetDisplayText(EndPos.Y),EndPos.X+1,255));
             BackSpace;
-          end;
-        eaInsertText :
-          begin
-            SetCurPtr(startpos.x,startpos.y);
-            for Temp := 1 to length(Text^) do
-              DelChar;
-            { remove text }
+            SetCurPtr(StartPos.X,StartPos.Y);
           end;
         eaDeleteLine :
           begin
-            { reinsert deleted line }
-            SCP:=CurPos;
-            SetCurPtr(StartPos.X,StartPos.Y);
+            SetCurPtr(EndPos.X,EndPos.Y);
             InsertLine;
             SetCurPtr(StartPos.X,StartPos.Y);
             SetLineText(StartPos.Y,GetStr(Text));
-            SetCurPtr(SCP.X,SCP.Y);
-          end;
-        eaDeleteText :
-          begin
-            { reinsert deleted text }
-            SetCurPtr(startpos.x,startpos.y);
-            for Temp := 1 to length(Text^) do
-              AddChar(Text^[Temp]);
           end;
         eaSelectionChanged :
           begin
@@ -3061,18 +3089,20 @@ begin
       end; { once this lot is done paste into redo and modify to suit needs }
       { move item to redo stack }
       RedoList^.Insert(UndoList^.At(Idx));
-      UpdateUndoRedo(cmRedo,PEditorAction(UndoList^.At(Idx))^.Action);
+      UpdateUndoRedo(cmRedo,UndoList^.At(Idx)^.Action);
       UndoList^.atDelete(Idx);
       If Idx>0 then
-        UpdateUndoRedo(cmUndo,PEditorAction(UndoList^.At(Idx-1))^.Action)
+        UpdateUndoRedo(cmUndo,UndoList^.At(Idx-1)^.Action)
       else
         UpdateUndoRedo(cmUndo,0);
       if UndoList^.count=0 then
         SetCmdState(UndoCmd,false);
       SetCmdState(RedoCmd,true);
+      Message(Application,evBroadcast,cmCommandSetChanged,nil);
     end;
   end;
   StoreUndo := True;
+  Unlock;
 {$else}
   NotImplemented; Exit;
 {$endif Undo}
@@ -3082,11 +3112,11 @@ procedure TCodeEditor.Redo;
 {$ifdef Undo}
 var
   Idx,Temp : Longint;
-  SCP : Tpoint;
 {$endif Undo}
 begin
 {$ifdef Undo}
   StoreUndo := False;
+  Lock;
   if RedoList^.count <> 0 then
   begin
     Idx:=RedoList^.count-1;
@@ -3096,34 +3126,28 @@ begin
         eaMoveCursor :
           begin
             { move cursor back to original position }
-            SetCurPtr(endpos.x,endpos.y);
-          end;
-        eaInsertLine :
-          begin
-            SetCurPtr(StartPos.X,StartPos.Y);
-            InsertLine;
-            { move cursor to inserted line, already done by other undo action?}
-            { delete inserted line}
-            { move cursor to end of line above }
-            { insert text that had been moved to line below }
+            SetCurPtr(EndPos.X,EndPos.Y);
           end;
         eaInsertText :
           begin
             SetCurPtr(startpos.x,startpos.y);
             InsertText(GetStr(Text));
           end;
-        eaDeleteLine :
-          begin
-            SetCurPtr(StartPos.X,StartPos.Y);
-            DeleteLine(EndPos.Y);
-            { insert line deleted }
-          end;
         eaDeleteText :
           begin
-            SetCurPtr(startpos.x,startpos.y);
+            SetCurPtr(EndPos.X,EndPos.Y);
             for Temp := 1 to length(GetStr(Text)) do
               DelChar;
-            { insert deleted text }
+          end;
+        eaInsertLine :
+          begin
+            SetCurPtr(StartPos.X,StartPos.Y);
+            InsertLine;
+          end;
+        eaDeleteLine :
+          begin
+            SetCurPtr(StartPos.X,StartPos.Y);
+            DeleteLine(EndPos.Y);
           end;
         eaSelectionChanged :
           begin
@@ -3143,9 +3167,11 @@ begin
       if RedoList^.count=0 then
         SetCmdState(RedoCmd,false);
       SetCmdState(UndoCmd,true);
+      Message(Application,evBroadcast,cmCommandSetChanged,nil);
     end;
   end;
   StoreUndo := True;
+  Unlock;
 {$else}
   NotImplemented; Exit;
 {$endif Undo}
@@ -3915,7 +3941,7 @@ var OK: boolean;
     StartPos,DestPos: TPoint;
     LineStartX,LineEndX: Sw_integer;
     S,OrigS,AfterS: string;
-    OneLineOnly,VerticalBlock: boolean;
+    VerticalBlock: boolean;
     SEnd: TPoint;
 begin
   Lock;
@@ -4012,11 +4038,13 @@ procedure TCodeEditor.AddAction(AAction: byte; AStartPos, AEndPos: TPoint; AText
 var
   ActionIntegrated : boolean;
   pa : PEditorAction;
+  S : String;
 begin
   if (UndoList=nil) or (not StoreUndo) then Exit;
+  ActionIntegrated:=false;
   if UndoList^.count>0 then
     begin
-      pa:=PEditorAction(UndoList^.At(UndoList^.count-1));
+      pa:=UndoList^.At(UndoList^.count-1);
       if (pa^.action=AAction) and
          (pa^.EndPos.X=AStartPos.X) and
          (pa^.EndPos.Y=AStartPos.Y) {and
@@ -4024,21 +4052,23 @@ begin
          then
         begin
           pa^.EndPos:=AEndPos;
-          pa^.text:=NewStr(GetStr(pa^.text)+AText);
+          S:=GetStr(pa^.text);
+          if S<>'' then
+           DisposeStr(pa^.text);
+          pa^.text:=NewStr(S+AText);
           ActionIntegrated:=true;
         end;
-    end
-  else
-    ActionIntegrated:=false;
+    end;
   if not ActionIntegrated then
     begin
       UndoList^.Insert(New(PEditorAction,Init(AAction,AStartPos,AEndPos,AText)));
       UpdateUndoRedo(cmUndo,AAction);
     end;
-  if UndoList^.count <> 0 then
+  if UndoList^.count>0 then
   begin
     SetCmdState(UndoCmd,true);
     SetCmdState(RedoCmd,false);
+    Message(Application,evBroadcast,cmCommandSetChanged,nil);
     UpdateUndoRedo(cmRedo,0);
     RedoList^.FreeAll;
   end;
@@ -4117,8 +4147,8 @@ begin
   CanPaste:=(Clipboard<>nil) and ((Clipboard^.SelStart.X<>Clipboard^.SelEnd.X) or
        (Clipboard^.SelStart.Y<>Clipboard^.SelEnd.Y));
   SetCmdState(FromClipCmds,CanPaste  and (Clipboard<>@Self));
-  SetCmdState(UndoCmd,StoreUndo and (UndoList^.count>0));
-  SetCmdState(RedoCmd,StoreUndo and (RedoList^.count>0));
+  SetCmdState(UndoCmd,(UndoList^.count>0));
+  SetCmdState(RedoCmd,(RedoList^.count>0));
   Message(Application,evBroadcast,cmCommandSetChanged,nil);
   DrawView;
 end;
@@ -4317,6 +4347,12 @@ destructor TEditorAction.done;
 begin
   DisposeStr(Text);
 end;
+
+function TEditorActionCollection.At(Idx : sw_integer) : PEditorAction;
+begin
+  At:=PEditorAction(Inherited At(Idx));
+end;
+
 {$else}
 procedure TEditorActionCollection.FreeItem(Item: Pointer);
 begin
@@ -4857,7 +4893,10 @@ end;
 END.
 {
   $Log$
-  Revision 1.54  1999-10-25 16:49:05  pierre
+  Revision 1.55  1999-10-27 10:46:19  pierre
+   * More Undo/Redo stuff
+
+  Revision 1.54  1999/10/25 16:49:05  pierre
     + Undo/Redo by Visa Harvey (great thanks) inserted
       (with some modifications)
       Moves work correctly