IDE: free designer on idle, do not free while processing the closequery

git-svn-id: trunk@34737 -
This commit is contained in:
mattias 2012-01-14 18:18:25 +00:00
parent 984566c793
commit 0bf369ec20
4 changed files with 70 additions and 39 deletions

View File

@ -254,6 +254,7 @@ type
AControlSelection: TControlSelection);
procedure PrepareFreeDesigner(AFreeComponent: boolean);
procedure FinalizeFreeDesigner;
procedure DisconnectComponent; override;
destructor Destroy; override;
procedure Modified; override;
@ -590,6 +591,7 @@ constructor TDesigner.Create(TheDesignerForm: TCustomForm;
AControlSelection: TControlSelection);
begin
inherited Create;
//debugln(['TDesigner.Create Self=',dbgs(Pointer(Self)),' TheDesignerForm=',DbgSName(TheDesignerForm)]);
FForm := TheDesignerForm;
if FForm is TNonControlDesignerForm then begin
FLookupRoot := TNonControlDesignerForm(FForm).LookupRoot;
@ -628,42 +630,32 @@ begin
end;
procedure TDesigner.FinalizeFreeDesigner;
var
i: Integer;
begin
//debugln(['TDesigner.FinalizeFreeDesigner Self=',dbgs(Pointer(Self))]);
Include(FFlags, dfDestroyingForm);
if FLookupRoot is TComponent then
begin
// unselect
if TheControlSelection.LookupRoot = FLookupRoot then
begin
TheControlSelection.BeginUpdate;
TheControlSelection.Clear;
TheControlSelection.EndUpdate;
end;
if GlobalDesignHook.LookupRoot = FLookupRoot then
GlobalDesignHook.LookupRoot := nil;
if FFreeComponent then
begin
// tell hooks about deleting
for i := FLookupRoot.ComponentCount - 1 downto 0 do
GlobalDesignHook.PersistentDeleting(FLookupRoot.Components[i]);
GlobalDesignHook.PersistentDeleting(FLookupRoot);
end;
// delete
if Form <> nil then
Form.Designer := nil;
if Mediator<>nil then
Mediator.Designer:=nil;
// free or hide the form
TheFormEditor.DeleteComponent(FLookupRoot,FFreeComponent);
TheFormEditor.DeleteComponent(TComponent(FLookupRoot),FFreeComponent);
end;
DisconnectComponent;
Free;
end;
procedure TDesigner.DisconnectComponent;
begin
//debugln(['TDesigner.DisconnectComponent Self=',dbgs(Pointer(Self))]);
inherited DisconnectComponent;
if Mediator<>nil then begin
Mediator.Designer:=nil;
FMediator:=nil;
end;
Free;
FLookupRoot:=nil;
end;
destructor TDesigner.Destroy;
begin
//debugln(['TDesigner.Destroy Self=',dbgs(Pointer(Self))]);
PopupMenuComponentEditor := nil;
FreeAndNil(FDesignerPopupMenu);
FreeAndNil(FHintWIndow);

View File

@ -45,7 +45,7 @@ uses
// IDEIntf
PropEdits, PropEditUtils, ObjectInspector, IDECommands, FormEditingIntf,
// IDE
LazarusIDEStrConsts, Project, JITForms, MainIntf,
LazarusIDEStrConsts, ControlSelection, Project, JITForms, MainIntf,
CustomNonFormDesigner, NonControlDesigner, FrameDesigner,
ComponentReg, IDEProcs, ComponentEditors, KeyMapping, EditorOptions,
EnvironmentOpts, DesignerProcs;
@ -460,28 +460,52 @@ var
AForm: TCustomForm;
AWinControl: TWinControl;
IsJIT: Boolean;
i: Integer;
aDesigner: TIDesigner;
Begin
IsJIT:=IsJITComponent(AComponent);
{$IFDEF IDE_DEBUG}
DebugLn(['TCustomFormEditor.DeleteComponent ',DbgSName(AComponent),' IsJITComponent=',IsJITComponent(AComponent),' FreeComponent=',FreeComponent]);
DebugLn(['TCustomFormEditor.DeleteComponent ',DbgSName(AComponent),' IsJITComponent=',IsJIT,' FreeComponent=',FreeComponent]);
{$ENDIF}
if TheControlSelection.LookupRoot = AComponent then
begin
TheControlSelection.BeginUpdate;
try
TheControlSelection.Clear;
finally
TheControlSelection.EndUpdate;
end;
end;
if PropertyEditorHook.LookupRoot=AComponent then
PropertyEditorHook.LookupRoot:=nil;
IsJIT:=IsJITComponent(AComponent);
if IsJIT then begin
// value is a top level component
// AComponent is a top level component
if FreeComponent then
begin
// tell hooks about deleting
for i := AComponent.ComponentCount - 1 downto 0 do
PropertyEditorHook.PersistentDeleting(AComponent.Components[i]);
PropertyEditorHook.PersistentDeleting(AComponent);
end;
// disconnect designer
aDesigner:=GetDesignerByComponent(AComponent);
if aDesigner is TComponentEditorDesigner then
TComponentEditorDesigner(aDesigner).DisconnectComponent;
if JITFormList.IsJITForm(AComponent) then begin
// free/unbind a form component
if FreeComponent then
JITFormList.DestroyJITComponent(AComponent);
end else if JITNonFormList.IsJITNonForm(AComponent) then begin
// free/unbind a non form component and its designer form
AForm:=GetDesignerForm(AComponent);
aForm:=GetDesignerForm(AComponent);
if (AForm<>nil) and (not (AForm is TCustomNonFormDesignerForm)) then
RaiseException(Format(
lisCFETCustomFormEditorDeleteComponentWhereIsTheTCustomN, [AComponent.
ClassName]));
if (AForm <> nil) and (AForm is TCustomNonFormDesignerForm) then
if (AForm <> nil) then
begin
FNonFormForms.Remove(AForm);
TCustomNonFormDesignerForm(AForm).LookupRoot := nil;

View File

@ -635,7 +635,7 @@ type
out aBounds: TRect; out DockSibling: string; out DockAlign: TAlign);
private
FUserInputSinceLastIdle: boolean;
FDesignerToBeFreed: TDesigner; // Will be freed in OnIdle.
FDesignerToBeFreed: TFilenameToStringTree; // form file names to be freed OnIdle.
FDisplayState: TDisplayState;
FLastFormActivated: TCustomForm;// used to find the last form so you can
// display the correct tab
@ -1508,6 +1508,7 @@ begin
TheControlSelection.OnSelectionFormChanged:=nil;
end;
FreeAndNil(FDesignerToBeFreed);
FreeAndNil(JumpHistoryViewWin);
FreeAndNil(ComponentListForm);
FreeThenNil(ProjInspector);
@ -7461,10 +7462,7 @@ procedure TMainIDE.FreeDesigner(AnUnitInfo: TUnitInfo; ADesigner: TDesigner;
begin
AnUnitInfo.LoadedDesigner:=false;
ADesigner.PrepareFreeDesigner(AFreeComponent);
if ADesigner.ProcessingDesignerEvent > 0 then
FDesignerToBeFreed:=ADesigner // Free it later on idle time.
else
ADesigner.FinalizeFreeDesigner; // Free it now.
ADesigner.FinalizeFreeDesigner;
end;
{-------------------------------------------------------------------------------
@ -16447,7 +16445,9 @@ begin
Exit;
end;
end;
CloseUnitComponent(AnUnitInfo,[]);
if FDesignerToBeFreed=nil then
FDesignerToBeFreed:=TFilenameToStringTree.Create(false);
FDesignerToBeFreed[AnUnitInfo.Filename]:='1';
end;
procedure TMainIDE.OnDesignerRenameComponent(ADesigner: TDesigner;
@ -17140,6 +17140,7 @@ var
AnUnitInfo: TUnitInfo;
AnIDesigner: TIDesigner;
HasResources: Boolean;
FileItem: PStringToStringTreeItem;
begin
if FNeedUpdateHighlighters then begin
{$IFDEF VerboseIdle}
@ -17152,8 +17153,14 @@ begin
if (SplashForm<>nil) then FreeThenNil(SplashForm);
if Assigned(FDesignerToBeFreed) then begin
FDesignerToBeFreed.FinalizeFreeDesigner;
FDesignerToBeFreed:=Nil;
for FileItem in FDesignerToBeFreed do begin
if Project1=nil then break;
AnUnitInfo:=Project1.UnitInfoWithFilename(FileItem^.Name);
if AnUnitInfo=nil then continue;
if AnUnitInfo.Component=nil then continue;
CloseUnitComponent(AnUnitInfo,[]);
end;
FreeAndNil(FDesignerToBeFreed);
end;
if FUserInputSinceLastIdle then
begin

View File

@ -74,6 +74,7 @@ type
property PropertyEditorHook: TPropertyEditorHook read GetPropertyEditorHook;
property Form: TCustomForm read FForm;
property ChangeStamp: int64 read FChangeStamp;// increased on calling Modified
procedure DisconnectComponent; virtual;
public
// Handlers
procedure RemoveAllHandlersForObject(const HandlerObject: TObject);
@ -1474,6 +1475,13 @@ begin
FHandlers[cedhtModified].CallNotifyEvents(Self);
end;
procedure TComponentEditorDesigner.DisconnectComponent;
begin
if Form=nil then exit;
Form.Designer:=nil;
FForm:=nil;
end;
procedure TComponentEditorDesigner.RemoveAllHandlersForObject(
const HandlerObject: TObject);
var