From b69bf50553fd96022fb2f37baed598a9ff868d92 Mon Sep 17 00:00:00 2001 From: mattias Date: Wed, 8 Oct 2014 17:46:51 +0000 Subject: [PATCH] IDE: designer: clean up undo code git-svn-id: trunk@46476 - --- designer/controlselection.pp | 41 +++++++++++----------- designer/designer.pp | 68 ++++++++++++++++++++---------------- 2 files changed, 59 insertions(+), 50 deletions(-) diff --git a/designer/controlselection.pp b/designer/controlselection.pp index 46c14734cb..23dc460ade 100644 --- a/designer/controlselection.pp +++ b/designer/controlselection.pp @@ -37,9 +37,13 @@ interface { $DEFINE VerboseDesigner} uses - Classes, SysUtils, Math, types, LCLIntf, LCLType, LCLProc, Controls, Forms, - GraphType, Graphics, Menus, EnvironmentOpts, PropEditUtils, - FormEditingIntf, NonControlDesigner, DesignerProcs; + Classes, SysUtils, Math, types, + // LCL + LCLIntf, LCLType, LCLProc, Controls, Forms, GraphType, Graphics, Menus, + // IDEIntf + PropEditUtils, ComponentEditors, FormEditingIntf, + // IDE + EnvironmentOpts, NonControlDesigner, DesignerProcs; type TArrSize = array of array [0 .. 3] of integer; @@ -272,6 +276,7 @@ type TControlSelection = class(TComponent) private FControls: TList; // list of TSelectedControl + FDesigner: TComponentEditorDesigner; FMediator: TDesignerMediator; // current bounds of the selection (only valid if Count>0) @@ -513,6 +518,7 @@ type property Visible:boolean read GetVisible write SetVisible; property SelectionForm: TCustomForm read FForm; + property Designer: TComponentEditorDesigner read FDesigner; property Mediator: TDesignerMediator read FMediator; property OnSelectionFormChanged: TOnSelectionFormChanged read FOnSelectionFormChanged write FOnSelectionFormChanged; @@ -526,9 +532,6 @@ var TheControlSelection: TControlSelection; implementation -uses - ComponentEditors; - const GRAB_CURSOR: array[TGrabIndex] of TCursor = ( crSizeNW, crSizeN, crSizeNE, @@ -1013,8 +1016,6 @@ begin end; procedure TControlSelection.BeginResizing(IsStartUndo: boolean); -var - CompEditDesig: TComponentEditorDesigner; begin if FResizeLockCount=0 then BeginUpdate; inc(FResizeLockCount); @@ -1022,9 +1023,8 @@ begin SetLength(arrOldSize, Count); GetCompSize(arrOldSize); - CompEditDesig := FindRootDesigner(Items[0].Persistent) as TComponentEditorDesigner; - if (Count > 0) and (CompEditDesig.FUndoState = ucsNone) and IsStartUndo then - CompEditDesig.FUndoState := ucsStartChange; + if (Designer<>nil) and (Count > 0) and (Designer.FUndoState = ucsNone) and IsStartUndo then + Designer.FUndoState := ucsStartChange; end; procedure TControlSelection.EndResizing(ApplyUserBounds, ActionIsProcess: boolean); @@ -1034,24 +1034,21 @@ var function SaveAct(AIndex: integer): boolean; var CurrComp: TComponent; - RootDesigner: TIDesigner; begin Result := false; - RootDesigner := FindRootDesigner(Items[AIndex].Persistent); - if ((RootDesigner as TComponentEditorDesigner).FUndoState = ucsStartChange) + if (Designer.FUndoState = ucsStartChange) and Items[AIndex].IsTComponent then begin - if SelectionForm.Name = TComponent(Items[AIndex].Persistent).Name then - CurrComp := SelectionForm - else - CurrComp := SelectionForm.FindComponent(TComponent(Items[AIndex].Persistent).Name); - Result := (CurrComp <> nil) and (RootDesigner is TComponentEditorDesigner) and + CurrComp := TComponent(Items[AIndex].Persistent); + if (SelectionForm <> CurrComp) and (CurrComp.Owner<>SelectionForm) then + exit; + Result := ((arrOldSize[AIndex, 0] <> arrNewSize[AIndex, 0]) or (arrOldSize[AIndex, 1] <> arrNewSize[AIndex, 1]) or (arrOldSize[AIndex, 2] <> arrNewSize[AIndex, 2]) or (arrOldSize[AIndex, 3] <> arrNewSize[AIndex, 3])); if Result then - with (RootDesigner as TComponentEditorDesigner) do + with Designer do begin AddUndoAction(CurrComp, uopChange, not(IsActionsBegin), 'Top', arrOldSize[AIndex, 0], arrNewSize[AIndex, 0]); @@ -1178,6 +1175,9 @@ begin else FMediator:=nil; FLookupRoot:=GetSelectionOwner; + FDesigner:=nil; + if Count>0 then + FDesigner:=TComponentEditorDesigner(FindRootDesigner(Items[0].Persistent)); if Assigned(FOnSelectionFormChanged) then FOnSelectionFormChanged(Self,OldCustomForm,NewCustomForm); end; @@ -2291,6 +2291,7 @@ begin FStates:=FStates+cssSelectionChangeFlags-[cssLookupRootSelected]; FForm:=nil; FMediator:=nil; + FDesigner:=nil; UpdateBounds; SaveBounds; DoChange; diff --git a/designer/designer.pp b/designer/designer.pp index de13dbd6f3..c78e49cc5b 100644 --- a/designer/designer.pp +++ b/designer/designer.pp @@ -47,9 +47,10 @@ uses FormEditingIntf, ComponentReg, // IDE LazarusIDEStrConsts, EnvironmentOpts, IDECommands, LazIDEIntf, ProjectIntf, - LazFileUtils, NonControlDesigner, FrameDesigner, AlignCompsDlg, SizeCompsDlg, - ScaleCompsDlg, TabOrderDlg, AnchorEditor, DesignerProcs, CustomFormEditor, - AskCompNameDlg, ControlSelection, ChangeClassDialog, EditorOptions; + LazFileUtils, LazFileCache, NonControlDesigner, FrameDesigner, AlignCompsDlg, + SizeCompsDlg, ScaleCompsDlg, TabOrderDlg, AnchorEditor, DesignerProcs, + CustomFormEditor, AskCompNameDlg, ControlSelection, ChangeClassDialog, + EditorOptions; type TDesigner = class; @@ -89,7 +90,7 @@ type compName, parentName: TComponentName; opType: TUndoOpType; isValid: Boolean; - id: int64; + GroupId: int64; end; { TDesigner } @@ -128,7 +129,7 @@ type FUndoList: array of TUndoItem; FUndoCurr: integer; FUndoLock: integer; - FUndoActId: int64; + FUndoGroupId: int64; //hint stuff FHintTimer: TTimer; @@ -209,8 +210,8 @@ type function DoUndo: Boolean; function DoRedo: Boolean; - procedure SetNewVal(IsActUndo: boolean); - procedure SetNextUndoActId; + procedure ExecuteUndoItem(IsActUndo: boolean); + procedure SetNextUndoGroupId; inline; procedure DoShowAnchorEditor; procedure DoShowTabOrderEditor; @@ -294,7 +295,7 @@ type function Undo: Boolean; override; function Redo: Boolean; override; function AddUndoAction(const aPersistent: TPersistent; aOpType: TUndoOpType; - IsSetNewId: boolean; aFieldName: string; const aOldVal, aNewVal: variant): boolean; override; + StartNewGroup: boolean; aFieldName: string; const aOldVal, aNewVal: variant): boolean; override; function IsUndoLocked: boolean; override; procedure ClearUndoItem(AIndex: Integer); @@ -611,6 +612,12 @@ begin 'Show options',dlgFROpts, nil, nil, nil, 'menu_environment_options'); end; +// inline +procedure TDesigner.SetNextUndoGroupId; +begin + LUIncreaseChangeStamp64(FUndoGroupId); +end; + constructor TDesigner.Create(TheDesignerForm: TCustomForm; AControlSelection: TControlSelection); var @@ -654,7 +661,7 @@ begin FUndoCurr := Low(FUndoList); FUndoLock := 0; FUndoState := ucsNone; - SetNextUndoActId; + FUndoGroupId := 1; end; procedure TDesigner.PrepareFreeDesigner(AFreeComponent: boolean); @@ -1230,30 +1237,30 @@ begin end; function TDesigner.DoUndo: Boolean; -var currId: int64; +var GroupId: int64; begin repeat Result := CanUndo; if not Result then Exit; Dec(FUndoCurr); - currId := FUndoList[FUndoCurr].id; - SetNewVal(true); - until (FUndoCurr=Low(FUndoList)) or (currId <> FUndoList[FUndoCurr - 1].id); + GroupId := FUndoList[FUndoCurr].GroupId; + ExecuteUndoItem(true); + until (FUndoCurr=Low(FUndoList)) or (GroupId <> FUndoList[FUndoCurr - 1].GroupId); end; function TDesigner.DoRedo: Boolean; -var currId: int64; +var GroupId: int64; begin repeat Result := CanRedo; if not Result then Exit; - SetNewVal(false); - currId := FUndoList[FUndoCurr].id; + ExecuteUndoItem(false); + GroupId := FUndoList[FUndoCurr].GroupId; Inc(FUndoCurr); - until (FUndoCurr>High(FUndoList)) or (currId <> FUndoList[FUndoCurr].id); + until (FUndoCurr>High(FUndoList)) or (GroupId <> FUndoList[FUndoCurr].GroupId); end; -procedure TDesigner.SetNewVal(IsActUndo: boolean); +procedure TDesigner.ExecuteUndoItem(IsActUndo: boolean); procedure SetPropVal(AVal: variant); var @@ -1374,12 +1381,6 @@ begin PropertyEditorHook.RefreshPropertyValues; end; -procedure TDesigner.SetNextUndoActId; -begin - Randomize; - FUndoActId := Random(High(Int64)); -end; - procedure TDesigner.DoShowAnchorEditor; begin if Assigned(FOnShowAnchorEditor) then @@ -1607,7 +1608,7 @@ begin end; function TDesigner.AddUndoAction(const aPersistent: TPersistent; - aOpType: TUndoOpType; IsSetNewId: boolean; aFieldName: string; const aOldVal, + aOpType: TUndoOpType; StartNewGroup: boolean; aFieldName: string; const aOldVal, aNewVal: variant): boolean; procedure ShiftUndoList; @@ -1627,8 +1628,15 @@ var begin Result := (FUndoLock = 0); if not Result then Exit; + APropInfo := GetPropInfo(aPersistent, aFieldName); - {property is not published ?} + if APropInfo=nil then + begin + // property is not published + debugln(['WARNING: TDesigner.AddUndoAction: property "',aFieldName,'" not published of ',DbgSName(aPersistent)]); + exit(false); + end; + Inc(FUndoLock); try if FUndoCurr > High(FUndoList) then @@ -1641,8 +1649,8 @@ begin Inc(i); end; - if IsSetNewId then - SetNextUndoActId; + if StartNewGroup then + SetNextUndoGroupId; if (aOpType in [uopAdd, uopDelete]) and (FForm <> aPersistent) then begin @@ -1679,7 +1687,7 @@ begin end; opType := aOpType; isValid := true; - id := FUndoActId; + GroupId := FUndoGroupId; if APropInfo <> nil then propInfo := APropInfo^ else begin @@ -1710,7 +1718,7 @@ begin parentName := ''; opType := uopNone; isValid := false; - id := 0; + GroupId := 0; end; end;