IDE: improved renaming inherited components

git-svn-id: trunk@10082 -
This commit is contained in:
mattias 2006-10-16 18:20:42 +00:00
parent 19fac7a31f
commit 00b85598ab
7 changed files with 205 additions and 53 deletions

View File

@ -146,11 +146,11 @@ type
function PaintControl(Sender: TControl; TheMessage: TLMPaint):boolean;
function SizeControl(Sender: TControl; TheMessage: TLMSize):boolean;
function MoveControl(Sender: TControl; TheMessage: TLMMove):boolean;
Procedure MouseDownOnControl(Sender: TControl; var TheMessage : TLMMouse);
Procedure MouseMoveOnControl(Sender: TControl; var TheMessage: TLMMouse);
Procedure MouseUpOnControl(Sender: TControl; var TheMessage:TLMMouse);
Procedure KeyDown(Sender: TControl; var TheMessage:TLMKEY);
Procedure KeyUp(Sender: TControl; var TheMessage:TLMKEY);
procedure MouseDownOnControl(Sender: TControl; var TheMessage : TLMMouse);
procedure MouseMoveOnControl(Sender: TControl; var TheMessage: TLMMouse);
procedure MouseUpOnControl(Sender: TControl; var TheMessage:TLMMouse);
procedure KeyDown(Sender: TControl; var TheMessage:TLMKEY);
procedure KeyUp(Sender: TControl; var TheMessage:TLMKEY);
function HandleSetCursor(var TheMessage: TLMessage): boolean;
// procedures for working with components and persistents
@ -1823,18 +1823,34 @@ function TDesigner.DoDeleteSelectedPersistents: boolean;
var
i: integer;
APersistent: TPersistent;
AncestorRoot: TComponent;
begin
Result:=true;
if (ControlSelection.Count=0) or (ControlSelection.SelectionForm<>Form) then
exit;
Result:=false;
// check if a component is the lookup root (can not be deleted)
if (ControlSelection.LookupRootSelected) then begin
if ControlSelection.Count>1 then
MessageDlg(lisInvalidDelete,
lisTheRootComponentCanNotBeDeleted, mtInformation,
[mbOk],0);
[mbCancel],0);
exit;
end;
// check if a selected component is inherited (can not be deleted)
for i:=0 to ControlSelection.Count-1 do begin
if not ControlSelection[i].IsTComponent then continue;
AncestorRoot:=TheFormEditor.GetAncestorLookupRoot(
TComponent(ControlSelection[i].Persistent));
if AncestorRoot<>nil then begin
MessageDlg(lisInvalidDelete,
'The component '+dbgsName(ControlSelection[i].Persistent)
+' is inherited from '+dbgsName(AncestorRoot)+'.'#13
+'To delete an inherited component open the ancestor and delete it there.',
mtInformation, [mbCancel],0);
exit;
end;
end;
// mark selected components for deletion
for i:=0 to ControlSelection.Count-1 do
MarkPersistentForDeletion(ControlSelection[i].Persistent);
@ -1842,16 +1858,19 @@ begin
SelectOnlyThisComponent(FLookupRoot);
// delete marked components
Include(FFlags,dfDeleting);
if DeletingPersistent.Count=0 then exit;
while DeletingPersistent.Count>0 do begin
APersistent:=TPersistent(DeletingPersistent[DeletingPersistent.Count-1]);
//writeln('TDesigner.DoDeleteSelectedComponents A ',AComponent.Name,':',AComponent.ClassName,' ',DbgS(AComponent));
RemovePersistentAndChilds(APersistent);
//writeln('TDesigner.DoDeleteSelectedComponents B ',DeletingPersistent.IndexOf(AComponent));
try
if DeletingPersistent.Count=0 then exit;
while DeletingPersistent.Count>0 do begin
APersistent:=TPersistent(DeletingPersistent[DeletingPersistent.Count-1]);
//writeln('TDesigner.DoDeleteSelectedComponents A ',AComponent.Name,':',AComponent.ClassName,' ',DbgS(AComponent));
RemovePersistentAndChilds(APersistent);
//writeln('TDesigner.DoDeleteSelectedComponents B ',DeletingPersistent.IndexOf(AComponent));
end;
IgnoreDeletingPersistent.Clear;
finally
Exclude(FFlags,dfDeleting);
Modified;
end;
IgnoreDeletingPersistent.Clear;
Exclude(FFlags,dfDeleting);
Modified;
Result:=true;
end;
@ -2086,42 +2105,18 @@ end;
procedure TDesigner.ValidateRename(AComponent: TComponent;
const CurName, NewName: string);
{$IFDEF VER2_0_2}
procedure RaiseInvalidName(ConflictComponent: TComponent);
begin
raise EComponentError.Create(Format(
lisDesThereIsAlreadyAnotherComponentWithTheName, ['"',
ConflictComponent.Name, '"']));
end;
var
i: Integer;
CurComponent: TComponent;
{$ENDIF}
begin
// check if component is initialized
if (CurName='') or (NewName='')
or ((AComponent<>nil) and (csDestroying in AComponent.ComponentState)) then
exit;
{$IFDEF VER2_0_2}
// check, if there is already such a component
for i:=0 to FLookupRoot.ComponentCount-1 do begin
CurComponent:=FLookupRoot.Components[i];
//DebugLn('TDesigner.ValidateRename ',CurComponent.Name,' ',NewName);
if (CurComponent<>AComponent)
and (CompareText(CurComponent.Name,NewName)=0) then begin
RaiseInvalidName(CurComponent);
end;
end;
{$ENDIF}
// check if component is the LookupRoot
if AComponent=nil then AComponent:=FLookupRoot;
// consistency check
if CurName<>AComponent.Name then
DebugLn('WARNING: TDesigner.ValidateRename: OldComponentName="',CurName,'"');
DebugLn('WARNING: TDesigner.ValidateRename: OldComponentName="',CurName,'" <> AComponent=',dbgsName(AComponent));
if Assigned(OnRenameComponent) then
OnRenameComponent(Self,AComponent,NewName);
end;

View File

@ -148,7 +148,8 @@ type
procedure DestroyJITComponent(Index: integer);
function IndexOf(JITComponent: TComponent): integer;
function Contains(JITComponent: TComponent): boolean;
function FindComponentByClassName(const AClassName: shortstring):integer;
function FindComponentByClassName(const AClassName: shortstring): integer;
function FindComponentByClass(AClass: TComponentClass): integer;
function FindComponentByName(const AName: shortstring): integer;
procedure GetUnusedNames(var ComponentName, ComponentClassName: shortstring);
procedure AddNewMethod(JITComponent: TComponent; const AName: ShortString);
@ -613,6 +614,14 @@ begin
dec(Result);
end;
function TJITComponentList.FindComponentByClass(AClass: TComponentClass
): integer;
begin
Result:=FJITComponents.Count-1;
while (Result>=0) and (Items[Result].ClassType<>AClass) do
dec(Result);
end;
function TJITComponentList.FindComponentByName(const AName:shortstring):integer;
begin
Result:=FJITComponents.Count-1;
@ -1337,7 +1346,7 @@ procedure TJITComponentList.ReaderAncestorNotFound(Reader: TReader;
begin
// ToDo: this is for custom form templates
debugln('[TJITComponentList.ReaderAncestorNotFound] ComponentName='''+ComponentName
+''' Component='''+Component.Name+'''');
+''' Component='''+dbgsName(Component)+'''');
end;
procedure TJITComponentList.ReaderError(Reader: TReader;

View File

@ -162,6 +162,8 @@ each control that's dropped onto the form
function FindJITList(AComponent: TComponent): TJITComponentList;
function FindJITListByClassName(const AComponentClassName: string
): TJITComponentList;
function FindJITListByClass(AComponentClass: TComponentClass
): TJITComponentList;
function GetDesignerForm(AComponent: TComponent): TCustomForm; override;
function FindNonControlForm(LookupRoot: TComponent): TNonControlDesignerForm;
function CreateNonControlForm(LookupRoot: TComponent): TNonControlDesignerForm;
@ -177,7 +179,9 @@ each control that's dropped onto the form
procedure SaveHiddenDesignerFormProperties(AComponent: TComponent);
function FindJITComponentByClassName(const AComponentClassName: string
): TComponent;
function FindJITComponentByClass(AComponentClass: TComponentClass
): TComponent;
// designers
function DesignerCount: integer; override;
function GetDesigner(Index: integer): TIDesigner; override;
@ -218,6 +222,10 @@ each control that's dropped onto the form
ParentControl: TWinControl): TIComponentInterface; override;
procedure SetComponentNameAndClass(CI: TIComponentInterface;
const NewName, NewClassName: shortstring);
// ancestors
function GetAncestorLookupRoot(AComponent: TComponent): TComponent; override;
function GetAncestorInstance(AComponent: TComponent): TComponent; override;
// define properties
procedure FindDefineProperty(const APersistentClassName,
@ -1079,6 +1087,17 @@ begin
Result:=nil;
end;
function TCustomFormEditor.FindJITListByClass(AComponentClass: TComponentClass
): TJITComponentList;
begin
if JITFormList.FindComponentByClass(AComponentClass)>=0 then
Result:=JITFormList
else if JITNonFormList.FindComponentByClass(AComponentClass)>=0 then
Result:=JITNonFormList
else
Result:=nil;
end;
function TCustomFormEditor.GetDesignerForm(AComponent: TComponent
): TCustomForm;
var
@ -1189,15 +1208,37 @@ end;
function TCustomFormEditor.FindJITComponentByClassName(
const AComponentClassName: string): TComponent;
var
JITComponentList: TJITComponentList;
i: LongInt;
begin
Result:=nil;
JITComponentList:=FindJITListByClassName(AComponentClassName);
if JITComponentList=nil then exit;
i:=JITComponentList.FindComponentByClassName(AComponentClassName);
if i<0 then exit;
Result:=JITComponentList[i];
i:=JITFormList.FindComponentByClassName(AComponentClassName);
if i>=0 then begin
Result:=JITFormList[i];
exit;
end;
i:=JITNonFormList.FindComponentByClassName(AComponentClassName);
if i>=0 then begin
Result:=JITNonFormList[i];
exit;
end;
end;
function TCustomFormEditor.FindJITComponentByClass(
AComponentClass: TComponentClass): TComponent;
var
i: LongInt;
begin
Result:=nil;
i:=JITFormList.FindComponentByClass(AComponentClass);
if i>=0 then begin
Result:=JITFormList[i];
exit;
end;
i:=JITNonFormList.FindComponentByClass(AComponentClass);
if i>=0 then begin
Result:=JITNonFormList[i];
exit;
end;
end;
function TCustomFormEditor.DesignerCount: integer;
@ -1521,6 +1562,35 @@ begin
AComponent.Name:=NewName;
end;
function TCustomFormEditor.GetAncestorLookupRoot(AComponent: TComponent
): TComponent;
var
CurRoot: TComponent;
AncestorRoot: TComponent;
begin
Result:=nil;
if AComponent=nil then exit;
CurRoot:=AComponent.Owner;
if CurRoot=nil then exit;
repeat
// search in next ancestor
AncestorRoot:=GetAncestorInstance(CurRoot);
if AncestorRoot=nil then exit;
if AncestorRoot.FindComponent(AComponent.Name)=nil then exit;
// a better ancestor was found
Result:=AncestorRoot;
CurRoot:=AncestorRoot;
until false;
end;
function TCustomFormEditor.GetAncestorInstance(AComponent: TComponent
): TComponent;
begin
Result:=nil;
if (AComponent=nil) or (AComponent.ClassType=TComponent) then exit;
Result:=FindJITComponentByClass(TComponentClass(AComponent.ClassParent));
end;
procedure TCustomFormEditor.FindDefineProperty(
const APersistentClassName, AncestorClassName, Identifier: string;
var IsDefined: boolean);

View File

@ -493,6 +493,8 @@ type
{$ENDIF}
FRebuildingCompilerGraphCodeToolsDefinesNeeded: boolean;
FRenamingComponents: TFPList; // list of TComponents currently renaming
protected
procedure SetToolStatus(const AValue: TIDEToolStatus); override;
function DoResetToolStatus(Interactive: boolean): boolean;
@ -11400,6 +11402,8 @@ var
i: integer;
NewClassName: string;
BossResult: boolean;
AncestorRoot: TComponent;
s: String;
procedure ApplyBossResult(const ErrorMsg: string);
var
@ -11436,9 +11440,57 @@ var
end;
end;
procedure RenameInheritedComponents(RenamedUnit: TUnitInfo;
Simulate: boolean);
var
UsedByDependency: TUnitComponentDependency;
DependingUnit: TUnitInfo;
InheritedComponent: TComponent;
DependingDesigner: TCustomForm;
begin
UsedByDependency:=ActiveUnitInfo.FirstUsedByComponent;
while UsedByDependency<>nil do begin
DependingUnit:=UsedByDependency.UsedByUnit;
if (DependingUnit.Component<>nil)
and (DependingUnit.Component.ClassParent=RenamedUnit.Component.ClassType)
then begin
// the root component inherits from the DependingUnit root component
InheritedComponent:=
DependingUnit.Component.FindComponent(AComponent.Name);
if InheritedComponent<>nil then begin
// inherited component found
if FRenamingComponents=nil then
FRenamingComponents:=TFPList.Create;
FRenamingComponents.Add(InheritedComponent);
try
DebugLn(['RenameInheritedComponents ',dbgsName(InheritedComponent),' Owner=',dbgsName(InheritedComponent.Owner)]);
if Simulate then begin
InheritedComponent.ValidateRename(InheritedComponent,
InheritedComponent.Name,NewName);
end else begin
InheritedComponent.Name:=NewName;
DependingDesigner:=GetDesignerFormOfSource(DependingUnit,false);
if DependingDesigner<>nil then
DependingUnit.Modified:=true;
end;
finally
if FRenamingComponents<>nil then begin
FRenamingComponents.Remove(InheritedComponent);
if FRenamingComponents.Count=0 then
FreeThenNil(FRenamingComponents);
end;
end;
end;
// rename recursively
RenameInheritedComponents(DependingUnit,Simulate);
end;
UsedByDependency:=UsedByDependency.NextUsedByDependency;
end;
end;
begin
DebugLn('TMainIDE.OnDesignerRenameComponent Old=',AComponent.Name,':',AComponent.ClassName,' New=',NewName);
DebugLn('TMainIDE.OnDesignerRenameComponent Old=',AComponent.Name,':',AComponent.ClassName,' New=',NewName,' Owner=',dbgsName(AComponent.Owner));
if (not IsValidIdent(NewName)) or (NewName='') then
raise Exception.Create(Format(lisComponentNameIsNotAValidIdentifier, ['"',
Newname, '"']));
@ -11446,12 +11498,31 @@ begin
// this component was never added to the source. It is a new component.
exit;
end;
if (FRenamingComponents<>nil)
and (FRenamingComponents.IndexOf(AComponent)>=0) then begin
// already validated
exit;
end;
BeginCodeTool(ADesigner,ActiveSrcEdit,ActiveUnitInfo,[ctfSwitchToFormSource]);
ActiveUnitInfo:=Project1.UnitWithComponent(ADesigner.LookupRoot);
if CodeToolBoss.IsKeyWord(ActiveUnitInfo.Source,NewName) then
raise Exception.Create(Format(lisComponentNameIsKeyword, ['"', Newname, '"']
));
// check ancestor component
AncestorRoot:=FormEditor1.GetAncestorLookupRoot(AComponent);
if AncestorRoot<>nil then begin
s:='The component '+dbgsName(AComponent)
+' is inherited from '+dbgsName(AncestorRoot)+'.'#13
+'To rename an inherited component open the ancestor and rename it there.';
raise EComponentError.Create(s);
end;
// check inherited components
RenameInheritedComponents(ActiveUnitInfo,true);
if AComponent=ADesigner.LookupRoot then begin
// rename owner component (e.g. the form)
@ -11489,6 +11560,9 @@ begin
end else begin
RaiseException('TMainIDE.OnDesignerRenameComponent internal error:'+AComponent.Name+':'+AComponent.ClassName);
end;
// rename inherited components
RenameInheritedComponents(ActiveUnitInfo,false);
end;
procedure TMainIDE.OnDesignerViewLFM(Sender: TObject);

View File

@ -115,6 +115,10 @@ type
ParentControl: TWinControl
): TIComponentInterface; virtual; abstract;
// ancestors
function GetAncestorLookupRoot(AComponent: TComponent): TComponent; virtual; abstract;
function GetAncestorInstance(AComponent: TComponent): TComponent; virtual; abstract;
// designers
function DesignerCount: integer; virtual; abstract;
property Designer[Index: integer]: TIDesigner read GetDesigner;

View File

@ -519,7 +519,8 @@ begin
if not (pfAdded in APage.FFlags) then exit;
Exclude(APage.FFlags,pfAdded);
TWSCustomNotebookClass(WidgetSetClass).RemovePage(Self, APage.PageIndex);
APage.DestroyHandle;
if APage.HandleAllocated then
APage.DestroyHandle;
end;
end;

View File

@ -5651,7 +5651,6 @@ end;
function TGtkWidgetSet.GetSystemMetrics(nIndex: Integer): Integer;
var
P : Pointer;
ax,ay,ah,aw : gint;
begin
Assert(False, Format('Trace:> [TGtkWidgetSet.GetSystemMetrics] %d', [nIndex]));
case nIndex of