📄 packageinformation.pas
字号:
function TContainedFile.IsUsedByTarget(const TargetSymbol: string): Boolean;
begin
Result := IsIncluded(TargetSymbol);
end;
{ TPackageXmlInfo }
constructor TPackageXmlInfo.Create(const AFilename: string);
begin
inherited Create;
FFilename := AFilename;
FName := ChangeFileExt(ExtractFileName(FFilename), '');
FRequires := TObjectList.Create;
FContains := TObjectList.Create;
FIsDesign := EndsWith(Name, '-D', True); // do not localize
// IsDesign is updated in LoadFromFile
FC5Libs := TStringList.Create;
FC6Libs := TStringList.Create;
LoadFromFile(FFilename);
end;
destructor TPackageXmlInfo.Destroy;
begin
FC5Libs.Free;
FC6Libs.Free;
FRequires.Free;
FContains.Free;
inherited Destroy;
end;
function TPackageXmlInfo.GetContainCount: Integer;
begin
Result := FContains.Count;
end;
function TPackageXmlInfo.GetContains(Index: Integer): TContainedFile;
begin
Result := TContainedFile(FContains[Index]);
end;
function TPackageXmlInfo.GetRequireCount: Integer;
begin
Result := FRequires.Count;
end;
function TPackageXmlInfo.GetRequires(Index: Integer): TRequiredPackage;
begin
Result := TRequiredPackage(FRequires[Index]);
end;
procedure TPackageXmlInfo.LoadFromFile(const Filename: string);
var
i: Integer;
RequirePkgName, RequireTarget,
ContainsFileName, FormName, Condition: string;
xml: TJvSimpleXML;
RootNode : TJvSimpleXmlElemClassic;
RequiredNode: TJvSimpleXmlElem;
PackageNode: TJvSimpleXmlElem;
ContainsNode: TJvSimpleXmlElem;
FileNode: TJvSimpleXmlElem;
begin
FRequires.Clear;
FRequiresDB := False;
FContains.Clear;
xml := TJvSimpleXML.Create(nil);
try
xml.LoadFromFile(Filename);
RootNode := xml.Root;
FGUID := RootNode.Items.Value('GUID');
FC5PFlags := RootNode.Items.Value('C5PFlags');
FC6PFlags := RootNode.Items.Value('C6PFlags');
FC5Libs.CommaText := RootNode.Items.Value('C5Libs');
FC6Libs.CommaText := RootNode.Items.Value('C6Libs');
RequiredNode := RootNode.Items.ItemNamed['Requires']; // do not localize
ContainsNode := RootNode.Items.ItemNamed['Contains']; // do not localize
FDisplayName := RootNode.Properties.Value('Name'); // do not localize
FIsDesign := RootNode.Properties.BoolValue('Design', IsDesign); // do not localize
FIsXPlatform := RootNode.Properties.BoolValue('XPlatform', False); // do not localize
FDescription := RootNode.Items.Value('Description'); // do not localize
FClxDescription := RootNode.Items.Value('ClxDescription'); // do not localize
// requires
for i := 0 to RequiredNode.Items.Count -1 do
begin
PackageNode := RequiredNode.Items[i];
RequirePkgName := PackageNode.Properties.Value('Name'); // do not localize
if Pos('dcldb', AnsiLowerCase(RequirePkgName)) > 0 then // do not localize
FRequiresDB := True;
// require only designtime packages
RequireTarget := PackageNode.Properties.Value('Targets'); // do not localize
if RequireTarget = '' then
RequireTarget := 'all'; // do not localize
Condition := PackageNode.Properties.Value('Condition'); // do not localize
// add new require item
FRequires.Add(TRequiredPackage.Create(RequirePkgName, RequireTarget, Condition));
end;
// contains
for i := 0 to ContainsNode.Items.Count -1 do
begin
FileNode := ContainsNode.Items[i];
ContainsFileName := FileNode.Properties.ItemNamed['Name'].Value; // do not localize
RequireTarget := FileNode.Properties.Value('Targets'); // do not localize
if RequireTarget = '' then
RequireTarget := 'all'; // do not localize
FormName := FileNode.Properties.Value('Formname'); // do not localize
Condition := FileNode.Properties.Value('Condition'); // do not localize
// add new require item
FContains.Add(TContainedFile.Create(ContainsFileName, RequireTarget, FormName, Condition));
end;
finally
xml.Free;
end;
end;
{ TPackageGroup }
constructor TPackageGroup.Create(const AFilename, APackagesXmlDir, ATargetSymbol: string);
begin
inherited Create;
FPackagesXmlDir := APackagesXmlDir;
if (FPackagesXmlDir <> '') and (FPackagesXmlDir[Length(FPackagesXmlDir)] = PathDelim) then
Delete(FPackagesXmlDir, Length(FPackagesXmlDir), 1);
FTargetSymbol := ATargetSymbol;
FFilename := AFilename;
FPackages := TObjectList.Create(Filename <> '');
if Filename <> '' then
LoadFile;
end;
destructor TPackageGroup.Destroy;
begin
FPackages.Free;
inherited Destroy;
end;
function TPackageGroup.Add(const TargetName, SourceName: string): TBpgPackageTarget;
begin
Result := nil;
if FileExists(PackagesXmlDir + PathDelim + BplNameToGenericName(TargetName) + '.xml') then // do not localize
begin
try
Result := GetPackageTargetClass.Create(Self, TargetName, SourceName)
except
on E: EFOpenError do
FreeAndNil(Result);
end;
if Result <> nil then
FPackages.Add(Result);
end;
end;
procedure TPackageGroup.AddPackage(Pkg: TBpgPackageTarget);
begin
if Pkg <> nil then
FPackages.Add(Pkg);
end;
function TPackageGroup.FindPackageByXmlName(const XmlName: string): TBpgPackageTarget;
var
i: Integer;
begin
for i := 0 to Count - 1 do
begin
Result := Packages[i];
if CompareText(Result.Info.Name, XmlName) = 0 then
Exit;
end;
Result := nil;
end;
function TPackageGroup.GetBpgName: string;
begin
Result := ExtractFileName(Filename);
end;
function TPackageGroup.GetBplNameOf(Package: TRequiredPackage): string;
var
Pkg: TBpgPackageTarget;
begin
Pkg := FindPackagebyXmlName(Package.Name);
if Pkg <> nil then
Result := Pkg.TargetName
else
Result := Package.Name;
end;
function TPackageGroup.GetCount: Integer;
begin
Result := FPackages.Count;
end;
function TPackageGroup.GetIsVCLX: Boolean;
begin
Result := Pos('clx', LowerCase(BpgName)) > 0;
end;
function TPackageGroup.GetPackages(Index: Integer): TBpgPackageTarget;
begin
Result := TBpgPackageTarget(FPackages[Index]);
end;
function SortProc_PackageTarget(Item1, Item2: Pointer): Integer;
var
p1, p2: TBpgPackageTarget;
begin
p1 := Item1;
p2 := Item2;
Result := CompareText(p1.Info.DisplayName, p2.Info.DisplayName);
if Result = 0 then
begin
if p1.Info.IsDesign and not p2.Info.IsDesign then
Result := 1
else if not p1.Info.IsDesign and p2.Info.IsDesign then
Result := -1;
end;
end;
function TPackageGroup.GetPackageTargetClass: TBpgPackageTargetClass;
begin
Result := TBpgPackageTarget;
end;
procedure TPackageGroup.LoadFile;
var
i: Integer;
begin
if CompareText(ExtractFileExt(FileName), '.bdsgroup') = 0 then
LoadBDSGroupFile
else
LoadBPGFile;
// we use dependencies so the order is irrelevant and we can alpha sort. [Comment from Installer]
FPackages.Sort(SortProc_PackageTarget);
// update dependencies after all package targets are created
for i := 0 to Count - 1 do
Packages[i].GetDependencies;
end;
procedure TPackageGroup.LoadBDSGroupFile;
var
xml: TJvSimpleXML;
Options, Projects: TJvSimpleXMLElem;
i, OptIndex, PrjIndex: Integer;
Personality: string;
TgName: string;
begin
xml := TJvSimpleXML.Create(nil);
try
xml.LoadFromString(LoadUtf8File(Filename));
for i := 0 to xml.Root.Items.Count - 1 do
begin
if (CompareText(xml.Root.Items[i].Name, 'PersonalityInfo') = 0) and // <PersonalityInfo>
(xml.Root.Items[i].Items.Count > 0) then
begin
// find correct Personality
Options := xml.Root.Items[i].Items[0];
if CompareText(Options.Name, 'Option') = 0 then
begin
for OptIndex := 0 to Options.Items.Count - 1 do
if CompareText(Options.Items[OptIndex].Properties.Value('Name'), 'Personality') = 0 then
begin
Personality := Options.Items[OptIndex].Value;
Break;
end;
end;
end
else
if (CompareText(xml.Root.Items[i].Name, Personality) = 0) and
(xml.Root.Items[i].Items.Count > 0) and
(CompareText(xml.Root.Items[i].Items[0].Name, 'Projects') = 0) then
begin
// Read project list
Projects := xml.Root.Items[i].Items[0];
for PrjIndex := 0 to Projects.Items.Count - 1 do
begin
TgName := Projects.Items[PrjIndex].Properties.Value('Name');
if CompareText(TgName, 'Targets') <> 0 then
// change .bdsproj to .dpk and add the target
Add(TgName, ChangeFileExt(Projects.Items[PrjIndex].Value, '.dpk'));
end;
end;
end;
finally
xml.Free;
end;
end;
procedure TPackageGroup.LoadBPGFile;
var
Lines: TStrings;
i, ps: Integer;
S: string;
TgName: string;
begin
Lines := TStringList.Create;
try
Lines.LoadFromFile(Filename);
i := 0;
// find "default:" target
while i < Lines.Count do
begin
if StartsWith(Lines[I], 'default:', True) then // do not localize
Break;
Inc(i);
end;
Inc(i, 2);
// now read the available targets
while i < Lines.Count do
begin
S := Lines[i];
// find targets
if S <> '' then
begin
if S[1] > #32 then
begin
ps := Pos(':', S);
if ps > 0 then
begin
TgName := TrimRight(Copy(S, 1, ps - 1));
// does the .xml file exists for this target? <-> is it a vaild target?
Add(TgName, Trim(Copy(S, ps + 1, MaxInt)));
end;
end;
end;
Inc(i);
end;
finally
Lines.Free;
end;
end;
{ TBpgPackageTarget }
constructor TBpgPackageTarget.Create(AOwner: TPackageGroup; const ATargetName,
ASourceName: string);
begin
inherited Create;
FOwner := AOwner;
FTargetName := ATargetName;
FSourceName := ASourceName;
FInfo := TPackageInfo.Create(Self, AOwner.PackagesXmlDir);
FRequireList := TList.Create;
FContaineList := TList.Create;
end;
destructor TBpgPackageTarget.Destroy;
begin
if AutoDeleteUserData then
FUserData.Free;
FRequireList.Free;
FContaineList.Free;
// FInfo is buffered and is destroyed by XmlFileCache
inherited Destroy;
end;
function TBpgPackageTarget.FindRuntimePackage: TBpgPackageTarget;
begin
Result := Owner.FindPackageByXmlName(Copy(Info.Name, 1, Length(Info.Name) - 1) + 'R'); // do not localize
end;
function TBpgPackageTarget.GetContainCount: Integer;
begin
UpdateContainList;
Result := FContaineList.Count;
end;
function TBpgPackageTarget.GetContains(Index: Integer): TContainedFile;
begin
UpdateContainList;
Result := TContainedFile(FContaineList[Index]);
end;
procedure TBpgPackageTarget.GetDependencies;
begin
// do nothing by default
end;
function TBpgPackageTarget.GetRelSourceDir: string;
begin
Result := ExtractFileDir(FSourceName);
end;
function TBpgPackageTarget.GetRequireCount: Integer;
begin
UpdateRequireList;
Result := FRequireList.Count;
end;
function TBpgPackageTarget.GetRequires(Index: Integer): TRequiredPackage;
begin
UpdateRequireList;
Result := TRequiredPackage(FRequireList[Index]);
end;
function TBpgPackageTarget.GetSourceDir: string;
begin
Result := FollowRelativeFilename(ExtractFileDir(Owner.Filename), RelSourceDir);
end;
procedure TBpgPackageTarget.UpdateContainList;
var
i: Integer;
begin
if FContaineList.Count = 0 then
begin
for i := 0 to Info.ContainCount - 1 do
if Info.Contains[i].IsUsedByTarget(Owner.TargetSymbol) then
FContaineList.Add(Info.Contains[i]);
end;
end;
procedure TBpgPackageTarget.UpdateRequireList;
var
i: Integer;
begin
if FRequireList.Count = 0 then
begin
for i := 0 to Info.RequireCount - 1 do
if Info.Requires[i].IsRequiredByTarget(Owner.TargetSymbol) then
FRequireList.Add(Info.Requires[i]);
end;
end;
{ TPackageInfo }
constructor TPackageInfo.Create(AOwner: TBpgPackageTarget; const AXmlDir: string);
begin
inherited Create;
FOwner := AOwner;
FXmlDir := AXmlDir;
FXmlInfo := GetPackageXmlInfo(Owner.TargetName, AXmlDir);
end;
function TPackageInfo.GetBplName: string;
begin
Result := Owner.TargetName;
end;
function TPackageInfo.GetContainCount: Integer;
begin
Result := FXmlInfo.ContainCount;
end;
function TPackageInfo.GetContains(Index: Integer): TContainedFile;
begin
Result := FXmlInfo.Contains[Index];
end;
function TPackageInfo.GetRequireCount: Integer;
begin
Result := FXmlInfo.RequireCount;
end;
function TPackageInfo.GetRequires(Index: Integer): TRequiredPackage;
begin
Result := FXmlInfo.Requires[Index];
end;
function TPackageInfo.GetDescription: string;
begin
Result := FXmlInfo.Description;
end;
function TPackageInfo.GetDisplayName: string;
begin
Result := FXmlInfo.DisplayName;
end;
function TPackageInfo.GetIsDesign: Boolean;
begin
Result := FXmlInfo.IsDesign;
end;
function TPackageInfo.GetName: string;
begin
Result := FXmlInfo.Name;
end;
function TPackageInfo.GetRequiresDB: Boolean;
begin
Result := FXmlInfo.RequiresDB;
end;
procedure FinalizeXmlFileCache;
var
i: Integer;
begin
for i := 0 to XmlFileCache.Count - 1 do
XmlFileCache.Objects[i].Free;
XmlFileCache.Free;
end;
initialization
XmlFileCache := TStringList.Create;
XmlFileCache.Sorted := True;
finalization
FinalizeXmlFileCache;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -