mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-14 22:19:20 +02:00
Packager: Support extra unit/package dependencies when dropping a component on a form. Issue #36654, patch from Sven Barth.
git-svn-id: trunk@62635 -
This commit is contained in:
parent
ec192ce438
commit
6255c7a36f
@ -453,6 +453,41 @@ procedure RegisterComponentEditor(ComponentClasses: array of TComponentClass;
|
|||||||
function GetComponentEditor(Component: TComponent;
|
function GetComponentEditor(Component: TComponent;
|
||||||
const Designer: TComponentEditorDesigner): TBaseComponentEditor;
|
const Designer: TComponentEditorDesigner): TBaseComponentEditor;
|
||||||
|
|
||||||
|
|
||||||
|
type
|
||||||
|
{ TComponentRequirements
|
||||||
|
|
||||||
|
Providing this class for a component class allows to influence the
|
||||||
|
requirements for that component (for example which units or packages should
|
||||||
|
be referenced upon adding the component to a form).
|
||||||
|
|
||||||
|
RequiredUnits
|
||||||
|
Called to determine the units that a component requires. By default the
|
||||||
|
Units parameter contains the unit the component is contained in.
|
||||||
|
|
||||||
|
RequiredPkgs
|
||||||
|
Called to determine the packages that a component requires. By default the
|
||||||
|
Pkgs parameter contains the packages of the units returned by RequiredUnits
|
||||||
|
}
|
||||||
|
TComponentRequirements = class
|
||||||
|
private
|
||||||
|
FComponentClass: TComponentClass;
|
||||||
|
public
|
||||||
|
constructor Create(AComponentClass: TComponentClass); virtual;
|
||||||
|
procedure RequiredUnits({%H-}Units: TStrings); virtual;
|
||||||
|
procedure RequiredPkgs({%H-}Pkgs: TStrings); virtual;
|
||||||
|
property ComponentClass: TComponentClass read FComponentClass;
|
||||||
|
end;
|
||||||
|
|
||||||
|
TComponentRequirementsClass = class of TComponentRequirements;
|
||||||
|
|
||||||
|
|
||||||
|
procedure RegisterComponentRequirements(ComponentClass: TComponentClass;
|
||||||
|
ComponentRequirements: TComponentRequirementsClass);
|
||||||
|
procedure RegisterComponentRequirements(ComponentClasses: array of TComponentClass;
|
||||||
|
ComponentRequirements: TComponentRequirementsClass);
|
||||||
|
function GetComponentRequirements(ComponentClass: TComponentClass): TComponentRequirements;
|
||||||
|
|
||||||
type
|
type
|
||||||
TPropertyEditorFilterFunc =
|
TPropertyEditorFilterFunc =
|
||||||
function(const ATestEditor: TPropertyEditor): Boolean of object;
|
function(const ATestEditor: TPropertyEditor): Boolean of object;
|
||||||
@ -1380,9 +1415,84 @@ end;
|
|||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
{ RegisterComponentRequirements }
|
||||||
|
type
|
||||||
|
PComponentClassReqRec = ^TComponentClassReqRec;
|
||||||
|
TComponentClassReqRec = record
|
||||||
|
ComponentClass: TComponentClass;
|
||||||
|
RequirementsClass: TComponentRequirementsClass;
|
||||||
|
end;
|
||||||
|
|
||||||
|
const
|
||||||
|
ComponentClassReqList: TList = Nil;
|
||||||
|
|
||||||
|
procedure RegisterComponentRequirements(ComponentClass: TComponentClass;
|
||||||
|
ComponentRequirements: TComponentRequirementsClass);
|
||||||
|
var
|
||||||
|
P: PComponentClassReqRec;
|
||||||
|
begin
|
||||||
|
if not Assigned(ComponentClass) or not Assigned(ComponentRequirements) then
|
||||||
|
Exit;
|
||||||
|
if not Assigned(ComponentClassReqList) then
|
||||||
|
ComponentClassReqList := TList.Create;
|
||||||
|
New(P);
|
||||||
|
P^.ComponentClass := ComponentClass;
|
||||||
|
P^.RequirementsClass := ComponentRequirements;
|
||||||
|
ComponentClassReqList.Add(P);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure RegisterComponentRequirements(ComponentClasses: array of TComponentClass;
|
||||||
|
ComponentRequirements: TComponentRequirementsClass);
|
||||||
|
var
|
||||||
|
I: Integer;
|
||||||
|
begin
|
||||||
|
for I := 0 to High(ComponentClasses) do
|
||||||
|
RegisterComponentRequirements(ComponentClasses[I], ComponentRequirements);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function GetComponentRequirements(ComponentClass: TComponentClass): TComponentRequirements;
|
||||||
|
var
|
||||||
|
I: Integer;
|
||||||
|
P: PComponentClassReqRec;
|
||||||
|
begin
|
||||||
|
if not Assigned(ComponentClass) or not Assigned(ComponentClassReqList) then
|
||||||
|
Exit(Nil);
|
||||||
|
for I := 0 to ComponentClassReqList.Count - 1 do
|
||||||
|
begin
|
||||||
|
P := PComponentClassReqRec(ComponentClassReqList[i]);
|
||||||
|
if P^.ComponentClass = ComponentClass then
|
||||||
|
begin
|
||||||
|
Result := P^.RequirementsClass.Create(ComponentClass);
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
Result := Nil;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TComponentRequirements }
|
||||||
|
|
||||||
|
constructor TComponentRequirements.Create(AComponentClass: TComponentClass);
|
||||||
|
begin
|
||||||
|
inherited Create;
|
||||||
|
FComponentClass := AComponentClass;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TComponentRequirements.RequiredUnits(Units: TStrings);
|
||||||
|
begin
|
||||||
|
; // Inherit classes can override as needed.
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TComponentRequirements.RequiredPkgs(Pkgs: TStrings);
|
||||||
|
begin
|
||||||
|
; // Inherit classes can override as needed.
|
||||||
|
end;
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
procedure InternalFinal;
|
procedure InternalFinal;
|
||||||
var
|
var
|
||||||
p: PComponentClassRec;
|
p: PComponentClassRec;
|
||||||
|
pq: PComponentClassReqRec;
|
||||||
i: integer;
|
i: integer;
|
||||||
begin
|
begin
|
||||||
if ComponentClassList<>nil then begin
|
if ComponentClassList<>nil then begin
|
||||||
@ -1392,6 +1502,13 @@ begin
|
|||||||
end;
|
end;
|
||||||
ComponentClassList.Free;
|
ComponentClassList.Free;
|
||||||
end;
|
end;
|
||||||
|
if Assigned(ComponentClassReqList) then begin
|
||||||
|
for i:=0 to ComponentClassReqList.Count-1 do begin
|
||||||
|
pq:=PComponentClassReqRec(ComponentClassReqList[i]);
|
||||||
|
Dispose(pq);
|
||||||
|
end;
|
||||||
|
ComponentClassReqList.Free;
|
||||||
|
end;
|
||||||
|
|
||||||
EditorForms.Free;
|
EditorForms.Free;
|
||||||
end;
|
end;
|
||||||
|
@ -57,10 +57,10 @@ uses
|
|||||||
CodeToolsConfig, CodeToolManager, CodeCache, BasicCodeTools,
|
CodeToolsConfig, CodeToolManager, CodeCache, BasicCodeTools,
|
||||||
FileProcs, CodeTree, CTUnitGraph,
|
FileProcs, CodeTree, CTUnitGraph,
|
||||||
// IDE Interface
|
// IDE Interface
|
||||||
IDECommands, NewItemIntf, ProjPackIntf, ProjectIntf,
|
IDECommands, NewItemIntf, ProjPackIntf, ProjectIntf, PackageIntf,
|
||||||
PackageIntf, PackageDependencyIntf, PackageLinkIntf,
|
PackageDependencyIntf, PackageLinkIntf, CompOptsIntf, MenuIntf, IDEWindowIntf,
|
||||||
CompOptsIntf, MenuIntf, IDEWindowIntf, IDEExternToolIntf, MacroIntf, LazIDEIntf,
|
IDEExternToolIntf, MacroIntf, LazIDEIntf, IDEMsgIntf, SrcEditorIntf,
|
||||||
IDEMsgIntf, SrcEditorIntf, ComponentReg, PropEdits, IDEDialogs, UnitResources,
|
ComponentReg, ComponentEditors, PropEdits, IDEDialogs, UnitResources,
|
||||||
// IDE
|
// IDE
|
||||||
IDECmdLine, LazarusIDEStrConsts, IDEProcs, ObjectLists,
|
IDECmdLine, LazarusIDEStrConsts, IDEProcs, ObjectLists,
|
||||||
DialogProcs, IDEOptionDefs, EnvironmentOpts,
|
DialogProcs, IDEOptionDefs, EnvironmentOpts,
|
||||||
@ -360,9 +360,14 @@ type
|
|||||||
function AddUnitDependenciesForComponentClasses(const UnitFilename: string;
|
function AddUnitDependenciesForComponentClasses(const UnitFilename: string;
|
||||||
ComponentClassnames: TStrings;
|
ComponentClassnames: TStrings;
|
||||||
Quiet: boolean = false): TModalResult; override;
|
Quiet: boolean = false): TModalResult; override;
|
||||||
|
function GetUnitsAndDependenciesForComponents(ComponentClassNames: TStrings;
|
||||||
|
out PackageList: TObjectArray; out UnitList: TStrings): TModalResult;
|
||||||
function GetMissingDependenciesForUnit(const UnitFilename: string;
|
function GetMissingDependenciesForUnit(const UnitFilename: string;
|
||||||
ComponentClassnames: TStrings;
|
ComponentClassnames: TStrings;
|
||||||
var List: TObjectArray): TModalResult;
|
var List: TObjectArray): TModalResult;
|
||||||
|
function FilterMissingDependenciesForUnit(const UnitFilename: string;
|
||||||
|
InputPackageList: TObjectArray;
|
||||||
|
out OutputPackageList: TObjectArray): TModalResult;
|
||||||
function GetUsableComponentUnits(CurRoot: TPersistent): TFPList; override; // list of TUnitInfo
|
function GetUsableComponentUnits(CurRoot: TPersistent): TFPList; override; // list of TUnitInfo
|
||||||
procedure IterateComponentNames(CurRoot: TPersistent; TypeData: PTypeData;
|
procedure IterateComponentNames(CurRoot: TPersistent; TypeData: PTypeData;
|
||||||
Proc: TGetStrProc); override;
|
Proc: TGetStrProc); override;
|
||||||
@ -4323,14 +4328,35 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
type
|
||||||
|
TPackageIterateHelper = class
|
||||||
|
public
|
||||||
|
PackageNames: TStrings;
|
||||||
|
PackageList: TStrings;
|
||||||
|
DefaultPackage: TLazPackageID;
|
||||||
|
procedure AddDependency(APackageID: TLazPackageID);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TPackageIterateHelper.AddDependency(APackageID: TLazPackageID);
|
||||||
|
begin
|
||||||
|
if Assigned(DefaultPackage) and (APackageID.IDAsString=DefaultPackage.IDAsString) then
|
||||||
|
Exit;
|
||||||
|
{ are we looking for this package? }
|
||||||
|
if PackageNames.IndexOf(APackageID.Name)<0 then
|
||||||
|
Exit;
|
||||||
|
{ was the package already added? }
|
||||||
|
if PackageList.IndexOf(APackageID.Name)>=0 then
|
||||||
|
Exit;
|
||||||
|
PackageList.AddObject(APackageID.Name,APackageID);
|
||||||
|
end;
|
||||||
|
|
||||||
function TPkgManager.AddUnitDependenciesForComponentClasses(
|
function TPkgManager.AddUnitDependenciesForComponentClasses(
|
||||||
const UnitFilename: string; ComponentClassnames: TStrings;
|
const UnitFilename: string; ComponentClassnames: TStrings;
|
||||||
Quiet: boolean): TModalResult;
|
Quiet: boolean): TModalResult;
|
||||||
var
|
var
|
||||||
UnitBuf: TCodeBuffer;
|
UnitBuf: TCodeBuffer;
|
||||||
UnitNames: TStringList;
|
UnitNames: TStrings;
|
||||||
Packages: TFPList;
|
Dependencies, MissingDependencies: TObjectArray;
|
||||||
MissingDependencies: TObjectArray;
|
|
||||||
|
|
||||||
function LoadAndParseUnitBuf: TModalResult;
|
function LoadAndParseUnitBuf: TModalResult;
|
||||||
begin
|
begin
|
||||||
@ -4349,49 +4375,6 @@ var
|
|||||||
Result:=mrOk;
|
Result:=mrOk;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function CollectNeededUnitnamesAndPackages: TModalResult;
|
|
||||||
var
|
|
||||||
i: Integer;
|
|
||||||
RegComp: TRegisteredComponent;
|
|
||||||
NewUnitName: String;
|
|
||||||
PkgFile: TPkgFile;
|
|
||||||
ClassUnitInfo: TUnitInfo;
|
|
||||||
APackage: TLazPackage;
|
|
||||||
begin
|
|
||||||
for i:=0 to ComponentClassnames.Count-1 do begin
|
|
||||||
//DebugLn(['CollectNeededUnitnamesAndPackages ComponentClassnames[i]=',ComponentClassnames[i]]);
|
|
||||||
RegComp:=IDEComponentPalette.FindComponent(ComponentClassnames[i]);
|
|
||||||
NewUnitName:='';
|
|
||||||
if (RegComp<>nil) then begin
|
|
||||||
if RegComp.ComponentClass<>nil then
|
|
||||||
NewUnitName:=GetClassUnitName(RegComp.ComponentClass);
|
|
||||||
//DebugLn(['CollectNeededUnitnamesAndPackages NewUnitName=',NewUnitName]);
|
|
||||||
if NewUnitName='' then
|
|
||||||
NewUnitName:=RegComp.GetUnitName;
|
|
||||||
end else begin
|
|
||||||
ClassUnitInfo:=Project1.UnitWithComponentClassName(ComponentClassnames[i]);
|
|
||||||
if ClassUnitInfo<>nil then
|
|
||||||
NewUnitName:=ClassUnitInfo.Unit_Name;
|
|
||||||
end;
|
|
||||||
if (NewUnitName<>'') and (UnitNames.IndexOf(NewUnitName)<0) then begin
|
|
||||||
// new needed unit
|
|
||||||
UnitNames.Add(NewUnitName);
|
|
||||||
// find package
|
|
||||||
PkgFile:=PackageGraph.FindUnitInAllPackages(NewUnitName,true);
|
|
||||||
//DebugLn(['CollectNeededUnitnamesAndPackages PkgFile=',PkgFile<>nil]);
|
|
||||||
if (PkgFile=nil) and (RegComp is TPkgComponent) then
|
|
||||||
PkgFile:=TPkgComponent(RegComp).PkgFile;
|
|
||||||
if (PkgFile<>nil) then begin
|
|
||||||
APackage:=PkgFile.LazPackage;
|
|
||||||
APackage:=TLazPackage(RedirectPackageDependency(APackage));
|
|
||||||
if (APackage<>nil) and (Packages.IndexOf(APackage)<0) then
|
|
||||||
Packages.Add(APackage);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
Result:=mrOk;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function RemoveExistingUnitnames: TModalResult;
|
function RemoveExistingUnitnames: TModalResult;
|
||||||
var
|
var
|
||||||
ImplementationUsesSection: TStrings;
|
ImplementationUsesSection: TStrings;
|
||||||
@ -4425,7 +4408,7 @@ var
|
|||||||
var
|
var
|
||||||
UsesAdditions: String;
|
UsesAdditions: String;
|
||||||
UnitOwner: TObject;
|
UnitOwner: TObject;
|
||||||
RequiredPackage: TLazPackage;
|
RequiredPackage: TLazPackageID;
|
||||||
i: Integer;
|
i: Integer;
|
||||||
PackageAdditions: String;
|
PackageAdditions: String;
|
||||||
Msg: String;
|
Msg: String;
|
||||||
@ -4440,8 +4423,9 @@ var
|
|||||||
if MissingDependencies<>nil then begin
|
if MissingDependencies<>nil then begin
|
||||||
for i:=0 to MissingDependencies.Count-1 do begin
|
for i:=0 to MissingDependencies.Count-1 do begin
|
||||||
UnitOwner:=TObject(MissingDependencies[i]);
|
UnitOwner:=TObject(MissingDependencies[i]);
|
||||||
RequiredPackage:=TLazPackage(MissingDependencies.Objects[i]);
|
RequiredPackage:=TLazPackageID(MissingDependencies.Objects[i]);
|
||||||
RequiredPackage:=TLazPackage(RedirectPackageDependency(RequiredPackage));
|
if RequiredPackage is TIDEPackage then
|
||||||
|
RequiredPackage:=RedirectPackageDependency(TIDEPackage(RequiredPackage));
|
||||||
if UnitOwner is TProject then begin
|
if UnitOwner is TProject then begin
|
||||||
PackageAdditions:=Format(lisPkgMangAddingNewDependencyForProjectPackage,
|
PackageAdditions:=Format(lisPkgMangAddingNewDependencyForProjectPackage,
|
||||||
[PackageAdditions, TProject(UnitOwner).GetTitle, RequiredPackage.Name]) + LineEnding+LineEnding;
|
[PackageAdditions, TProject(UnitOwner).GetTitle, RequiredPackage.Name]) + LineEnding+LineEnding;
|
||||||
@ -4471,16 +4455,24 @@ var
|
|||||||
var
|
var
|
||||||
i: Integer;
|
i: Integer;
|
||||||
UnitOwner: TObject;
|
UnitOwner: TObject;
|
||||||
RequiredPackage: TLazPackage;
|
RequiredPackage: TLazPackageID;
|
||||||
|
PkgDependency: TPkgDependency;
|
||||||
begin
|
begin
|
||||||
if MissingDependencies<>nil then begin
|
if MissingDependencies<>nil then begin
|
||||||
for i:=0 to MissingDependencies.Count-1 do begin
|
for i:=0 to MissingDependencies.Count-1 do begin
|
||||||
UnitOwner:=TObject(MissingDependencies[i]);
|
UnitOwner:=TObject(MissingDependencies[i]);
|
||||||
RequiredPackage:=TLazPackage(MissingDependencies.Objects[i]);
|
RequiredPackage:=TLazPackageID(MissingDependencies.Objects[i]);
|
||||||
RequiredPackage:=TLazPackage(RedirectPackageDependency(RequiredPackage));
|
if RequiredPackage is TIDEPackage then
|
||||||
|
RequiredPackage:=RedirectPackageDependency(TIDEPackage(RequiredPackage));
|
||||||
if UnitOwner is TProject then begin
|
if UnitOwner is TProject then begin
|
||||||
DebugLn('Hint: (lazarus) [TPkgManager.AddUnitDependenciesForComponentClasses] Adding Project Dependency ',TProject(UnitOwner).GetTitle,' -> ',RequiredPackage.Name);
|
DebugLn('Hint: (lazarus) [TPkgManager.AddUnitDependenciesForComponentClasses] Adding Project Dependency ',TProject(UnitOwner).GetTitle,' -> ',RequiredPackage.Name);
|
||||||
AddProjectDependency(TProject(UnitOwner),RequiredPackage);
|
if RequiredPackage is TLazPackage then
|
||||||
|
AddProjectDependency(TProject(UnitOwner),TLazPackage(RequiredPackage))
|
||||||
|
else begin
|
||||||
|
PkgDependency:=TPkgDependency.Create;
|
||||||
|
PkgDependency.PackageName:=RequiredPackage.Name;
|
||||||
|
AddProjectDependency(TProject(UnitOwner),PkgDependency);
|
||||||
|
end;
|
||||||
end else if UnitOwner is TLazPackage then begin
|
end else if UnitOwner is TLazPackage then begin
|
||||||
DebugLn('Hint: (lazarus) [TPkgManager.AddUnitDependenciesForComponentClasses] Adding Package Dependency ',TLazPackage(UnitOwner).Name,' -> ',RequiredPackage.Name);
|
DebugLn('Hint: (lazarus) [TPkgManager.AddUnitDependenciesForComponentClasses] Adding Package Dependency ',TLazPackage(UnitOwner).Name,' -> ',RequiredPackage.Name);
|
||||||
AddPackageDependency(TLazPackage(UnitOwner),RequiredPackage.Name);
|
AddPackageDependency(TLazPackage(UnitOwner),RequiredPackage.Name);
|
||||||
@ -4506,20 +4498,20 @@ var
|
|||||||
|
|
||||||
begin
|
begin
|
||||||
Result:=mrCancel;
|
Result:=mrCancel;
|
||||||
UnitNames:=TStringList.Create;
|
UnitNames:=nil;
|
||||||
Packages:=TFPList.Create;
|
Dependencies:=nil;
|
||||||
MissingDependencies:=nil;
|
MissingDependencies:=nil;
|
||||||
try
|
try
|
||||||
|
Result:=GetUnitsAndDependenciesForComponents(ComponentClassnames,
|
||||||
|
Dependencies,UnitNames);
|
||||||
|
if Result<>mrOk then exit;
|
||||||
|
|
||||||
Result:=CollectNeededUnitnamesAndPackages;
|
Result:=FilterMissingDependenciesForUnit(UnitFilename,Dependencies,MissingDependencies);
|
||||||
if Result<>mrOk then exit;
|
if Result<>mrOk then exit;
|
||||||
|
|
||||||
Result:=RemoveExistingUnitnames;
|
Result:=RemoveExistingUnitnames;
|
||||||
if Result<>mrOk then exit;
|
if Result<>mrOk then exit;
|
||||||
|
|
||||||
Result:=GetMissingDependenciesForUnit(UnitFilename,ComponentClassnames,
|
|
||||||
MissingDependencies);
|
|
||||||
if Result<>mrOk then exit;
|
|
||||||
if (UnitNames.Count=0) // no change needed
|
if (UnitNames.Count=0) // no change needed
|
||||||
and ((MissingDependencies=nil) or (MissingDependencies.Count=0)) then exit;
|
and ((MissingDependencies=nil) or (MissingDependencies.Count=0)) then exit;
|
||||||
|
|
||||||
@ -4537,29 +4529,126 @@ begin
|
|||||||
Result:=mrOk;
|
Result:=mrOk;
|
||||||
finally
|
finally
|
||||||
UnitNames.Free;
|
UnitNames.Free;
|
||||||
Packages.Free;
|
Dependencies.Free;
|
||||||
MissingDependencies.Free;
|
MissingDependencies.Free;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TPkgManager.GetMissingDependenciesForUnit(
|
function TPkgManager.GetUnitsAndDependenciesForComponents(
|
||||||
const UnitFilename: string; ComponentClassnames: TStrings;
|
ComponentClassNames: TStrings; out PackageList: TObjectArray;
|
||||||
var List: TObjectArray): TModalResult;
|
out UnitList: TStrings): TModalResult;
|
||||||
// returns a list of packages needed to use the Component in the unit
|
// returns a list of packages and units needed to use the Component in the unit
|
||||||
|
var
|
||||||
|
CurClassID: Integer;
|
||||||
|
CurUnitIdx, CurPackageIdx: Integer;
|
||||||
|
CurCompClass: string;
|
||||||
|
CurRegisteredComponent: TRegisteredComponent;
|
||||||
|
PkgFile: TPkgFile;
|
||||||
|
RequiredPackage: TLazPackageID;
|
||||||
|
CurUnitName: String;
|
||||||
|
CurPackages, AllPackages, CurUnitNames: TStrings;
|
||||||
|
CurCompReq: TComponentRequirements;
|
||||||
|
Helper: TPackageIterateHelper;
|
||||||
|
begin
|
||||||
|
Result:=mrCancel;
|
||||||
|
PackageList:=nil;
|
||||||
|
UnitList:=nil;
|
||||||
|
CurPackages:=nil;
|
||||||
|
AllPackages:=nil;
|
||||||
|
CurUnitNames:=TStringList.Create;
|
||||||
|
try
|
||||||
|
for CurClassID:=0 to ComponentClassnames.Count-1 do begin
|
||||||
|
CurCompClass:=ComponentClassnames[CurClassID];
|
||||||
|
CurRegisteredComponent:=IDEComponentPalette.FindComponent(CurCompClass);
|
||||||
|
if CurRegisteredComponent is TPkgComponent then begin
|
||||||
|
CurUnitName:='';
|
||||||
|
CurUnitNames.Clear;
|
||||||
|
CurCompReq:=nil;
|
||||||
|
try
|
||||||
|
if CurRegisteredComponent.ComponentClass<>nil then begin
|
||||||
|
CurUnitName:=GetClassUnitName(CurRegisteredComponent.ComponentClass);
|
||||||
|
CurCompReq:=GetComponentRequirements(CurRegisteredComponent.ComponentClass);
|
||||||
|
end;
|
||||||
|
//DebugLn(['TPkgManager.GetUnitsAndDependenciesForComponents CurUnitName=',CurUnitName]);
|
||||||
|
if CurUnitName='' then
|
||||||
|
CurUnitName:=CurRegisteredComponent.GetUnitName;
|
||||||
|
CurUnitNames.Add(CurUnitName);
|
||||||
|
if CurCompReq<>nil then
|
||||||
|
CurCompReq.RequiredUnits(CurUnitNames);
|
||||||
|
for CurUnitIdx:=0 to CurUnitNames.Count-1 do begin
|
||||||
|
if UnitList=nil then begin
|
||||||
|
UnitList:=TStringList.Create;
|
||||||
|
TStringList(UnitList).CaseSensitive:=False;
|
||||||
|
TStringList(UnitList).Duplicates:=dupIgnore;
|
||||||
|
end;
|
||||||
|
CurUnitName:=CurUnitNames[CurUnitIdx];
|
||||||
|
UnitList.Add(CurUnitName);
|
||||||
|
PkgFile:=PackageGraph.FindUnitInAllPackages(CurUnitName,true);
|
||||||
|
//DebugLn(['TPkgManager.GetUnitsAndDependenciesForComponents PkgFile=',PkgFile<>nil]);
|
||||||
|
if PkgFile=nil then
|
||||||
|
PkgFile:=TPkgComponent(CurRegisteredComponent).PkgFile;
|
||||||
|
if PkgFile<>nil then begin
|
||||||
|
RequiredPackage:=PkgFile.LazPackage;
|
||||||
|
RequiredPackage:=RedirectPackageDependency(TIDEPackage(RequiredPackage));
|
||||||
|
if RequiredPackage<>nil then begin
|
||||||
|
if CurPackages=nil then begin
|
||||||
|
CurPackages:=TStringList.Create;
|
||||||
|
TStringList(CurPackages).Duplicates:=dupIgnore;
|
||||||
|
TStringList(CurPackages).CaseSensitive:=False;
|
||||||
|
end else
|
||||||
|
CurPackages.Clear;
|
||||||
|
CurPackages.Add(RequiredPackage.Name);
|
||||||
|
if Assigned(CurCompReq) then
|
||||||
|
CurCompReq.RequiredPkgs(CurPackages);
|
||||||
|
Helper:=TPackageIterateHelper.Create;
|
||||||
|
try
|
||||||
|
if AllPackages=nil then begin
|
||||||
|
AllPackages:=TStringList.Create;
|
||||||
|
TStringList(AllPackages).CaseSensitive:=False;
|
||||||
|
TStringList(AllPackages).Duplicates:=dupIgnore;
|
||||||
|
end;
|
||||||
|
Helper.PackageNames:=CurPackages;
|
||||||
|
Helper.PackageList:=AllPackages;
|
||||||
|
Helper.DefaultPackage:=RequiredPackage;
|
||||||
|
PackageGraph.IteratePackages(fpfSearchAllExisting,@Helper.AddDependency);
|
||||||
|
finally
|
||||||
|
Helper.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
finally
|
||||||
|
CurCompReq.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
if AllPackages.Count>0 then begin
|
||||||
|
if AllPackages.Count>0 then PackageList:=TObjectArray.Create;
|
||||||
|
for CurPackageIdx:=0 to AllPackages.Count-1 do
|
||||||
|
PackageList.Add(AllPackages.Objects[CurPackageIdx]);
|
||||||
|
end;
|
||||||
|
finally
|
||||||
|
CurUnitNames.Free;
|
||||||
|
CurPackages.Free;
|
||||||
|
AllPackages.Free;
|
||||||
|
end;
|
||||||
|
Result:=mrOk;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TPkgManager.FilterMissingDependenciesForUnit(const UnitFilename: string;
|
||||||
|
InputPackageList: TObjectArray;
|
||||||
|
out OutputPackageList: TObjectArray): TModalResult;
|
||||||
|
// returns a list of packages that are not yet used by the project the unit
|
||||||
|
// belongs to
|
||||||
var
|
var
|
||||||
UnitOwners: TFPList;
|
UnitOwners: TFPList;
|
||||||
UnitOwner: TObject;
|
UnitOwner: TObject;
|
||||||
FirstDependency: TPkgDependency;
|
FirstDependency: TPkgDependency;
|
||||||
CurClassID: Integer;
|
CurOwnerID, CurPackageIdx: Integer;
|
||||||
CurOwnerID: Integer;
|
RequiredPackage: TLazPackageID;
|
||||||
CurCompClass: string;
|
|
||||||
CurRegisteredComponent: TRegisteredComponent;
|
|
||||||
PkgFile: TPkgFile;
|
|
||||||
RequiredPackage: TLazPackage;
|
|
||||||
CurUnitName: String;
|
|
||||||
begin
|
begin
|
||||||
Result:=mrCancel;
|
Result:=mrCancel;
|
||||||
List:=nil;
|
OutputPackageList:=nil;
|
||||||
UnitOwners:=GetOwnersOfUnit(UnitFilename);
|
UnitOwners:=GetOwnersOfUnit(UnitFilename);
|
||||||
if (UnitOwners<>nil) then begin
|
if (UnitOwners<>nil) then begin
|
||||||
for CurOwnerID:=0 to UnitOwners.Count-1 do begin
|
for CurOwnerID:=0 to UnitOwners.Count-1 do begin
|
||||||
@ -4570,47 +4659,50 @@ begin
|
|||||||
FirstDependency:=TLazPackage(UnitOwner).FirstRequiredDependency
|
FirstDependency:=TLazPackage(UnitOwner).FirstRequiredDependency
|
||||||
else
|
else
|
||||||
FirstDependency:=nil;
|
FirstDependency:=nil;
|
||||||
for CurClassID:=0 to ComponentClassnames.Count-1 do begin
|
for CurPackageIdx:=0 to InputPackageList.Count-1 do begin
|
||||||
CurCompClass:=ComponentClassnames[CurClassID];
|
RequiredPackage:=TLazPackageID(InputPackageList.Items[CurPackageIdx]);
|
||||||
CurRegisteredComponent:=IDEComponentPalette.FindComponent(CurCompClass);
|
if (RequiredPackage<>nil)
|
||||||
if CurRegisteredComponent is TPkgComponent then begin
|
and (RequiredPackage<>UnitOwner)
|
||||||
CurUnitName:='';
|
and (FindCompatibleDependencyInList(FirstDependency,pdlRequires,
|
||||||
if CurRegisteredComponent.ComponentClass<>nil then
|
RequiredPackage)=nil)
|
||||||
CurUnitName:=GetClassUnitName(CurRegisteredComponent.ComponentClass);
|
and (PackageGraph.FindPackageProvidingName(FirstDependency,
|
||||||
//DebugLn(['TPkgManager.GetMissingDependenciesForUnit CurUnitName=',CurUnitName]);
|
RequiredPackage.Name)=nil)
|
||||||
if CurUnitName='' then
|
then begin
|
||||||
CurUnitName:=CurRegisteredComponent.GetUnitName;
|
if OutputPackageList=nil then OutputPackageList:=TObjectArray.Create;
|
||||||
PkgFile:=PackageGraph.FindUnitInAllPackages(CurUnitName,true);
|
OutputPackageList.AddObject(UnitOwner,RequiredPackage);
|
||||||
//DebugLn(['TPkgManager.GetMissingDependenciesForUnit PkgFile=',PkgFile<>nil]);
|
//debugln(['TPkgManager.FilterMissingDependenciesForUnit A ',UnitOwner.ClassName,' ',RequiredPackage.Name]);
|
||||||
if PkgFile=nil then
|
//if TObject(OutputPackageList[OutputPackageList.Count-1])<>UnitOwner then RaiseGDBException('A');
|
||||||
PkgFile:=TPkgComponent(CurRegisteredComponent).PkgFile;
|
//if TObject(OutputPackageList.Objects[OutputPackageList.Count-1])<>RequiredPackage then RaiseGDBException('B');
|
||||||
if PkgFile<>nil then begin
|
|
||||||
RequiredPackage:=PkgFile.LazPackage;
|
|
||||||
RequiredPackage:=TLazPackage(RedirectPackageDependency(RequiredPackage));
|
|
||||||
if (RequiredPackage<>nil)
|
|
||||||
and (RequiredPackage<>UnitOwner)
|
|
||||||
and (FindCompatibleDependencyInList(FirstDependency,pdlRequires,
|
|
||||||
RequiredPackage)=nil)
|
|
||||||
and (PackageGraph.FindPackageProvidingName(FirstDependency,
|
|
||||||
RequiredPackage.Name)=nil)
|
|
||||||
then begin
|
|
||||||
if List=nil then List:=TObjectArray.Create;
|
|
||||||
List.AddObject(UnitOwner,RequiredPackage);
|
|
||||||
//debugln(['TPkgManager.GetMissingDependenciesForUnit A ',UnitOwner.ClassName,' ',RequiredPackage.Name]);
|
|
||||||
//if TObject(List[List.Count-1])<>UnitOwner then RaiseGDBException('A');
|
|
||||||
//if TObject(List.Objects[List.Count-1])<>RequiredPackage then RaiseGDBException('B');
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
UnitOwners.Free;
|
UnitOwners.Free;
|
||||||
end else begin
|
end else begin
|
||||||
DebugLn(['Warning: (lazarus) [TPkgManager.GetMissingDependenciesForUnit] unit has no owner: ',UnitFilename]);
|
DebugLn(['Warning: (lazarus) [TPkgManager.FilterMissingDependenciesForUnit] unit has no owner: ',UnitFilename]);
|
||||||
end;
|
end;
|
||||||
Result:=mrOk;
|
Result:=mrOk;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TPkgManager.GetMissingDependenciesForUnit(
|
||||||
|
const UnitFilename: string; ComponentClassnames: TStrings;
|
||||||
|
var List: TObjectArray): TModalResult;
|
||||||
|
// returns a list of packages needed to use the Component in the unit
|
||||||
|
var
|
||||||
|
AllPackages: TObjectArray;
|
||||||
|
AllUnits: TStrings;
|
||||||
|
begin
|
||||||
|
List:=nil;
|
||||||
|
Result:=GetUnitsAndDependenciesForComponents(ComponentClassnames,AllPackages,AllUnits);
|
||||||
|
try
|
||||||
|
if Result<>mrOK then Exit;
|
||||||
|
|
||||||
|
Result:=FilterMissingDependenciesForUnit(UnitFilename,AllPackages,List);
|
||||||
|
finally
|
||||||
|
AllPackages.Free;
|
||||||
|
AllUnits.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
function TPkgManager.GetOwnersOfUnit(const UnitFilename: string): TFPList;
|
function TPkgManager.GetOwnersOfUnit(const UnitFilename: string): TFPList;
|
||||||
begin
|
begin
|
||||||
Result:=GetPossibleOwnersOfUnit(UnitFilename,[]);
|
Result:=GetPossibleOwnersOfUnit(UnitFilename,[]);
|
||||||
|
Loading…
Reference in New Issue
Block a user