IDE: extended closing unit component with recursion

git-svn-id: trunk@10038 -
This commit is contained in:
mattias 2006-10-04 22:04:00 +00:00
parent e4ed3634af
commit 2f4f4bf6fa
3 changed files with 90 additions and 41 deletions

View File

@ -575,16 +575,21 @@ type
function DoLoadResourceFile(AnUnitInfo: TUnitInfo; function DoLoadResourceFile(AnUnitInfo: TUnitInfo;
var LFMCode, ResourceCode: TCodeBuffer; var LFMCode, ResourceCode: TCodeBuffer;
IgnoreSourceErrors: boolean): TModalResult; IgnoreSourceErrors: boolean): TModalResult;
function DoLoadLFM(AnUnitInfo: TUnitInfo; Flags: TOpenFlags): TModalResult; function DoLoadLFM(AnUnitInfo: TUnitInfo; OpenFlags: TOpenFlags;
CloseFlags: TCloseFlags): TModalResult;
function DoLoadLFM(AnUnitInfo: TUnitInfo; LFMBuf: TCodeBuffer; function DoLoadLFM(AnUnitInfo: TUnitInfo; LFMBuf: TCodeBuffer;
Flags: TOpenFlags; CloseDsgnForm: boolean): TModalResult; OpenFlags: TOpenFlags;
function DoLoadHiddenResourceComponent(AnUnitInfo: TUnitInfo; CloseFlags: TCloseFlags): TModalResult;
function DoLoadComponentDependencyHidden(AnUnitInfo: TUnitInfo;
const AComponentClassName: string; Flags: TOpenFlags; const AComponentClassName: string; Flags: TOpenFlags;
var AComponentClass: TComponentClass; var AComponentClass: TComponentClass;
var ComponentUnitInfo: TUnitInfo): TModalResult; var ComponentUnitInfo: TUnitInfo): TModalResult;
// methods for 'close unit' // methods for 'close unit'
function CloseUnitComponent(AnUnitInfo: TUnitInfo): TModalResult; function CloseUnitComponent(AnUnitInfo: TUnitInfo; Flags: TCloseFlags
): TModalResult;
function CloseDependingUnitComponents(AnUnitInfo: TUnitInfo;
Flags: TCloseFlags): TModalResult;
function UnitComponentIsUsed(AnUnitInfo: TUnitInfo; function UnitComponentIsUsed(AnUnitInfo: TUnitInfo;
CheckHasDesigner: boolean): boolean; CheckHasDesigner: boolean): boolean;
@ -4750,13 +4755,14 @@ begin
end; end;
function TMainIDE.DoLoadLFM(AnUnitInfo: TUnitInfo; function TMainIDE.DoLoadLFM(AnUnitInfo: TUnitInfo;
Flags: TOpenFlags): TModalResult; OpenFlags: TOpenFlags; CloseFlags: TCloseFlags): TModalResult;
// if there is a .lfm file, open the resource // if there is a .lfm file, open the resource
var var
LFMFilename: string; LFMFilename: string;
LFMBuf: TCodeBuffer; LFMBuf: TCodeBuffer;
begin begin
CloseUnitComponent(AnUnitInfo); Result:=CloseUnitComponent(AnUnitInfo,CloseFlags);
if Result<>mrOk then exit;
// Note: think about virtual and normal .lfm files. // Note: think about virtual and normal .lfm files.
LFMFilename:=ChangeFileExt(AnUnitInfo.Filename,'.lfm'); LFMFilename:=ChangeFileExt(AnUnitInfo.Filename,'.lfm');
@ -4772,11 +4778,12 @@ begin
Result:=LoadIDECodeBuffer(LFMBuf,LFMFilename,[lbfUpdateFromDisk]); Result:=LoadIDECodeBuffer(LFMBuf,LFMFilename,[lbfUpdateFromDisk]);
if Result<>mrOk then exit; if Result<>mrOk then exit;
Result:=DoLoadLFM(AnUnitInfo,LFMBuf,Flags,false); Result:=DoLoadLFM(AnUnitInfo,LFMBuf,OpenFlags,CloseFlags);
end; end;
function TMainIDE.DoLoadLFM(AnUnitInfo: TUnitInfo; LFMBuf: TCodeBuffer; function TMainIDE.DoLoadLFM(AnUnitInfo: TUnitInfo; LFMBuf: TCodeBuffer;
Flags: TOpenFlags; CloseDsgnForm: boolean): TModalResult; OpenFlags: TOpenFlags; CloseFlags: TCloseFlags
): TModalResult;
const const
BufSize = 4096; // allocating mem in 4k chunks helps many mem managers BufSize = 4096; // allocating mem in 4k chunks helps many mem managers
var var
@ -4802,12 +4809,8 @@ begin
end; end;
// close old designer form // close old designer form
if CloseDsgnForm then Result:=CloseUnitComponent(AnUnitInfo,CloseFlags);
CloseUnitComponent(AnUnitInfo) if Result<>mrOk then exit;
else if AnUnitInfo.Component<>nil then begin
DebugLn(['TMainIDE.DoLoadLFM INCONSISTENCY CloseDsgnForm=',CloseDsgnForm,' Filename=',AnUnitInfo.Filename,' Component=',dbgsName(AnUnitInfo.Component)]);
exit(mrAbort);
end;
//debugln('TMainIDE.DoLoadLFM LFM file loaded, parsing "',LFMBuf.Filename,'" ...'); //debugln('TMainIDE.DoLoadLFM LFM file loaded, parsing "',LFMBuf.Filename,'" ...');
@ -4860,7 +4863,7 @@ begin
// try loading the ancestor first (unit, lfm and component instance) // try loading the ancestor first (unit, lfm and component instance)
if (AncestorType=nil) then begin if (AncestorType=nil) then begin
Result:=DoLoadHiddenResourceComponent(AnUnitInfo,AncestorClassName,Flags, Result:=DoLoadComponentDependencyHidden(AnUnitInfo,AncestorClassName,OpenFlags,
AncestorType,AncestorUnitInfo); AncestorType,AncestorUnitInfo);
if Result=mrAbort then exit; if Result=mrAbort then exit;
if Result=mrOk then begin if Result=mrOk then begin
@ -4910,7 +4913,7 @@ begin
TxtLFMStream.Free; TxtLFMStream.Free;
end; end;
if ComponentLoadingOk then begin if ComponentLoadingOk then begin
if ([ofProjectLoading,ofLoadHiddenResource]*Flags=[]) then if ([ofProjectLoading,ofLoadHiddenResource]*OpenFlags=[]) then
FormEditor1.ClearSelection; FormEditor1.ClearSelection;
// create JIT component // create JIT component
@ -4925,7 +4928,7 @@ begin
DebugLn('ERROR: streaming failed lfm="',LFMBuf.Filename,'"'); DebugLn('ERROR: streaming failed lfm="',LFMBuf.Filename,'"');
// open lfm file in editor // open lfm file in editor
Result:=DoOpenEditorFile(LFMBuf.Filename,AnUnitInfo.EditorIndex+1, Result:=DoOpenEditorFile(LFMBuf.Filename,AnUnitInfo.EditorIndex+1,
Flags+[ofOnlyIfExists,ofQuiet,ofRegularFile]); OpenFlags+[ofOnlyIfExists,ofQuiet,ofRegularFile]);
if Result<>mrOk then exit; if Result<>mrOk then exit;
Result:=DoCheckLFMInEditor; Result:=DoCheckLFMInEditor;
if Result=mrOk then Result:=mrCancel; if Result=mrOk then Result:=mrCancel;
@ -4936,13 +4939,13 @@ begin
AnUnitInfo.ComponentName:=NewComponent.Name; AnUnitInfo.ComponentName:=NewComponent.Name;
AnUnitInfo.ComponentResourceName:=AnUnitInfo.ComponentName; AnUnitInfo.ComponentResourceName:=AnUnitInfo.ComponentName;
DesignerForm:=nil; DesignerForm:=nil;
if not (ofLoadHiddenResource in Flags) then begin if not (ofLoadHiddenResource in OpenFlags) then begin
CreateDesignerForComponent(NewComponent); CreateDesignerForComponent(NewComponent);
DesignerForm:=FormEditor1.GetDesignerForm(AnUnitInfo.Component); DesignerForm:=FormEditor1.GetDesignerForm(AnUnitInfo.Component);
end; end;
// select the new form (object inspector, formeditor, control selection) // select the new form (object inspector, formeditor, control selection)
if ([ofProjectLoading,ofLoadHiddenResource]*Flags=[]) then begin if ([ofProjectLoading,ofLoadHiddenResource]*OpenFlags=[]) then begin
FDisplayState:= dsForm; FDisplayState:= dsForm;
GlobalDesignHook.LookupRoot := NewComponent; GlobalDesignHook.LookupRoot := NewComponent;
TheControlSelection.AssignPersistent(NewComponent); TheControlSelection.AssignPersistent(NewComponent);
@ -4964,7 +4967,7 @@ begin
Result:=mrOk; Result:=mrOk;
end; end;
function TMainIDE.DoLoadHiddenResourceComponent(AnUnitInfo: TUnitInfo; function TMainIDE.DoLoadComponentDependencyHidden(AnUnitInfo: TUnitInfo;
const AComponentClassName: string; Flags: TOpenFlags; const AComponentClassName: string; Flags: TOpenFlags;
var AComponentClass: TComponentClass; var ComponentUnitInfo: TUnitInfo var AComponentClass: TComponentClass; var ComponentUnitInfo: TUnitInfo
): TModalResult; ): TModalResult;
@ -5033,7 +5036,7 @@ function TMainIDE.DoLoadHiddenResourceComponent(AnUnitInfo: TUnitInfo;
// load resource hidden // load resource hidden
TheModalResult:=DoLoadLFM(CurUnitInfo,LFMCode, TheModalResult:=DoLoadLFM(CurUnitInfo,LFMCode,
Flags+[ofLoadHiddenResource],false); Flags+[ofLoadHiddenResource],[]);
if (TheModalResult=mrOk) then begin if (TheModalResult=mrOk) then begin
ComponentUnitInfo:=CurUnitInfo; ComponentUnitInfo:=CurUnitInfo;
AComponentClass:=TComponentClass(ComponentUnitInfo.Component.ClassType); AComponentClass:=TComponentClass(ComponentUnitInfo.Component.ClassType);
@ -5129,7 +5132,8 @@ end;
Free the designer form of a unit. Free the designer form of a unit.
-------------------------------------------------------------------------------} -------------------------------------------------------------------------------}
function TMainIDE.CloseUnitComponent(AnUnitInfo: TUnitInfo): TModalResult; function TMainIDE.CloseUnitComponent(AnUnitInfo: TUnitInfo; Flags: TCloseFlags
): TModalResult;
procedure FreeUnusedComponents; procedure FreeUnusedComponents;
var var
@ -5138,7 +5142,7 @@ function TMainIDE.CloseUnitComponent(AnUnitInfo: TUnitInfo): TModalResult;
CompUnitInfo:=Project1.FirstUnitWithComponent; CompUnitInfo:=Project1.FirstUnitWithComponent;
while CompUnitInfo<>nil do begin while CompUnitInfo<>nil do begin
if not UnitComponentIsUsed(CompUnitInfo,true) then begin if not UnitComponentIsUsed(CompUnitInfo,true) then begin
CloseUnitComponent(CompUnitInfo); CloseUnitComponent(CompUnitInfo,Flags);
exit; exit;
end; end;
CompUnitInfo:=CompUnitInfo.NextUnitWithComponent; CompUnitInfo:=CompUnitInfo.NextUnitWithComponent;
@ -5150,9 +5154,21 @@ var
OldDesigner: TDesigner; OldDesigner: TDesigner;
LookupRoot: TComponent; LookupRoot: TComponent;
begin begin
Result:=mrOk;
LookupRoot:=AnUnitInfo.Component; LookupRoot:=AnUnitInfo.Component;
if LookupRoot=nil then exit; if LookupRoot=nil then exit(mrOk);
// save
if (cfSaveFirst in Flags) and (AnUnitInfo.EditorIndex>=0) then begin
Result:=DoSaveEditorFile(AnUnitInfo.EditorIndex,[sfCheckAmbiguousFiles]);
if Result<>mrOk then exit;
end;
// close dependencies
if cfCloseDependencies in Flags then begin
Result:=CloseDependingUnitComponents(AnUnitInfo,Flags);
if Result<>mrOk then exit;
end;
AForm:=FormEditor1.GetDesignerForm(LookupRoot); AForm:=FormEditor1.GetDesignerForm(LookupRoot);
OldDesigner:=nil; OldDesigner:=nil;
if AForm<>nil then if AForm<>nil then
@ -5189,6 +5205,34 @@ begin
Result:=mrOk; Result:=mrOk;
end; end;
function TMainIDE.CloseDependingUnitComponents(AnUnitInfo: TUnitInfo;
Flags: TCloseFlags): TModalResult;
var
DependingUnitInfo: TUnitInfo;
UserAsked: Boolean;
DependenciesFlags: TCloseFlags;
begin
Result:=mrCancel;
UserAsked:=false;
repeat
DependingUnitInfo:=Project1.UnitUsingComponentUnit(AnUnitInfo);
if DependingUnitInfo=nil then exit(mrOk);
if (not UserAsked) and (not (cfQuiet in Flags)) then begin
Result:=IDEQuestionDialog('Close component?',
'Close component '+dbgsName(DependingUnitInfo.Component)+'?',
mtConfirmation,[mrYes,mrAbort]);
if Result<>mrYes then exit;
UserAsked:=true;
end;
// close recursively
DependenciesFlags:=Flags+[cfCloseDependencies];
if cfSaveDependencies in Flags then
Include(DependenciesFlags,cfSaveFirst);
Result:=CloseUnitComponent(DependingUnitInfo,DependenciesFlags);
if Result<>mrOk then exit;
until false;
end;
function TMainIDE.UnitComponentIsUsed(AnUnitInfo: TUnitInfo; function TMainIDE.UnitComponentIsUsed(AnUnitInfo: TUnitInfo;
CheckHasDesigner: boolean): boolean; CheckHasDesigner: boolean): boolean;
var var
@ -5712,7 +5756,9 @@ begin
// the file is not really new // the file is not really new
NewUnitInfo:=AProject.Units[OldUnitIndex]; NewUnitInfo:=AProject.Units[OldUnitIndex];
// close form // close form
CloseUnitComponent(NewUnitInfo); Result:=CloseUnitComponent(NewUnitInfo,
[cfCloseDependencies,cfSaveDependencies]);
if Result<>mrOk then exit;
// assign source // assign source
NewUnitInfo.Source:=NewBuffer; NewUnitInfo.Source:=NewBuffer;
end else end else
@ -5777,7 +5823,7 @@ begin
LFMCode:=CodeToolBoss.CreateFile(LFMFilename); LFMCode:=CodeToolBoss.CreateFile(LFMFilename);
LFMCode.Source:=LFMSourceText; LFMCode.Source:=LFMSourceText;
//debugln('TMainIDE.DoNewEditorFile A ',LFMFilename); //debugln('TMainIDE.DoNewEditorFile A ',LFMFilename);
Result:=DoLoadLFM(NewUnitInfo,LFMCode,[],false); Result:=DoLoadLFM(NewUnitInfo,LFMCode,[],[]);
end else begin end else begin
// create a default form/datamodule // create a default form/datamodule
Result:=CreateNewForm(NewUnitInfo,AncestorType,nil); Result:=CreateNewForm(NewUnitInfo,AncestorType,nil);
@ -5981,11 +6027,11 @@ begin
end; end;
function TMainIDE.DoCloseEditorFile(PageIndex:integer; function TMainIDE.DoCloseEditorFile(PageIndex:integer;
Flags: TCloseFlags):TModalResult; Flags: TCloseFlags): TModalResult;
var ActiveSrcEdit: TSourceEditor; var ActiveSrcEdit: TSourceEditor;
ActiveUnitInfo: TUnitInfo; ActiveUnitInfo: TUnitInfo;
ACaption,AText: string; ACaption, AText: string;
i:integer; i: integer;
begin begin
debugln('TMainIDE.DoCloseEditorFile A PageIndex=',IntToStr(PageIndex)); debugln('TMainIDE.DoCloseEditorFile A PageIndex=',IntToStr(PageIndex));
Result:=mrCancel; Result:=mrCancel;
@ -6024,8 +6070,8 @@ begin
Result:=mrOk; Result:=mrOk;
end; end;
// close form // close form soft (keep it if used by another component)
CloseUnitComponent(ActiveUnitInfo); CloseUnitComponent(ActiveUnitInfo,[]);
// close source editor // close source editor
SourceNoteBook.CloseFile(PageIndex); SourceNoteBook.CloseFile(PageIndex);
@ -6090,16 +6136,19 @@ var
then begin then begin
// -> try to (re)load the lfm file // -> try to (re)load the lfm file
//debugln('TMainIDE.DoOpenEditorFile Loading LFM for ',NewUnitInfo.Filename); //debugln('TMainIDE.DoOpenEditorFile Loading LFM for ',NewUnitInfo.Filename);
Result:=DoLoadLFM(NewUnitInfo,Flags); Result:=DoLoadLFM(NewUnitInfo,Flags,
[cfCloseDependencies,cfSaveDependencies]);
if Result<>mrOk then exit; if Result<>mrOk then exit;
end else begin
Result:=mrOk;
end; end;
end else if NewUnitInfo.Component<>nil then begin end else if NewUnitInfo.Component<>nil then begin
// this is no pascal source and there is a designer form // this is no pascal source and there is a designer form
// This can be the case, when the file is renamed and reverted // This can be the case, when the file is renamed and reverted
// -> close form // -> close form
CloseUnitComponent(NewUnitInfo); Result:=CloseUnitComponent(NewUnitInfo,
[cfCloseDependencies,cfSaveDependencies]);
end; end;
Result:=mrOk;
end; end;
@ -9065,7 +9114,7 @@ begin
while AnUnitInfo<>nil do begin while AnUnitInfo<>nil do begin
NextUnitInfo:=AnUnitInfo.NextUnitWithComponent; NextUnitInfo:=AnUnitInfo.NextUnitWithComponent;
if not AnUnitInfo.NeedsSaveToDisk then if not AnUnitInfo.NeedsSaveToDisk then
CloseUnitComponent(AnUnitInfo); CloseUnitComponent(AnUnitInfo,[]);
AnUnitInfo:=NextUnitInfo; AnUnitInfo:=NextUnitInfo;
end; end;
end; end;
@ -11306,7 +11355,7 @@ begin
Exit; Exit;
end; end;
end; end;
CloseUnitComponent(AnUnitInfo); CloseUnitComponent(AnUnitInfo,[]);
end; end;
procedure TMainIDE.OnDesignerRenameComponent(ADesigner: TDesigner; procedure TMainIDE.OnDesignerRenameComponent(ADesigner: TDesigner;
@ -11893,7 +11942,7 @@ begin
Result:=nil; Result:=nil;
if (AnUnitInfo.Component=nil) and LoadForm if (AnUnitInfo.Component=nil) and LoadForm
and FilenameIsPascalSource(AnUnitInfo.Filename) then begin and FilenameIsPascalSource(AnUnitInfo.Filename) then begin
DoLoadLFM(AnUnitInfo,[]); DoLoadLFM(AnUnitInfo,[],[]);
end; end;
if AnUnitInfo.Component<>nil then if AnUnitInfo.Component<>nil then
Result:=FormEditor1.GetDesignerForm(AnUnitInfo.Component); Result:=FormEditor1.GetDesignerForm(AnUnitInfo.Component);

View File

@ -74,7 +74,9 @@ type
TCloseFlag = ( TCloseFlag = (
cfSaveFirst, // check if modified and save cfSaveFirst, // check if modified and save
cfQuiet, cfQuiet,
cfProjectClosing cfProjectClosing,
cfCloseDependencies,
cfSaveDependencies // set cfSaveFirst to closing the dependencies
); );
TCloseFlags = set of TCloseFlag; TCloseFlags = set of TCloseFlag;

View File

@ -1691,8 +1691,6 @@ end;
procedure TCustomForm.CreateWnd; procedure TCustomForm.CreateWnd;
begin begin
//DebugLn('TCustomForm.CreateWnd START ',ClassName); //DebugLn('TCustomForm.CreateWnd START ',ClassName);
if CompareText(ClassName,'TGrandMaForm')=0 then
RaiseGDBException('');
FFormState:=FFormState-[fsBorderStyleChanged,fsFormStyleChanged]; FFormState:=FFormState-[fsBorderStyleChanged,fsFormStyleChanged];
inherited CreateWnd; inherited CreateWnd;