mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-07-30 17:35:57 +02:00
IDE: improved renaming inherited components
git-svn-id: trunk@10082 -
This commit is contained in:
parent
19fac7a31f
commit
00b85598ab
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
76
ide/main.pp
76
ide/main.pp
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user