IDE: install pkg set dialog: changed available packages to custom structure, load overlay icons

git-svn-id: trunk@38605 -
This commit is contained in:
mattias 2012-09-09 20:47:18 +00:00
parent ecdb186fb6
commit cbaf2f7cd6
5 changed files with 1174 additions and 951 deletions

View File

@ -4247,7 +4247,8 @@ resourcestring
lisPckExplInstalled = 'Installed'; lisPckExplInstalled = 'Installed';
lisPckExplInstallOnNextStart = 'Install on next start'; lisPckExplInstallOnNextStart = 'Install on next start';
lisPckExplUninstallOnNextStart = 'Uninstall on next start'; lisPckExplUninstallOnNextStart = 'Uninstall on next start';
lisPckExplBase = 'Base, can not be uninstalled';
// project inspector // project inspector
lisProjInspConfirmDeletingDependency = 'Confirm deleting dependency'; lisProjInspConfirmDeletingDependency = 'Confirm deleting dependency';
lisProjInspConfirmRemovingFile = 'Confirm removing file'; lisProjInspConfirmRemovingFile = 'Confirm removing file';

File diff suppressed because it is too large Load Diff

View File

@ -204,32 +204,6 @@ debugger/debugger_watches.png
debugger/debugger_event_log.png debugger/debugger_event_log.png
debugger/evaluate_no_hist.png debugger/evaluate_no_hist.png
debugger/evaluate_up.png debugger/evaluate_up.png
packages/pkg_add.png
packages/pkg_graph.png
packages/pkg_inherited.png
packages/pkg_install.png
packages/pkg_installed.png
packages/pkg_open.png
packages/pkg_properties.png
packages/pkg_required.png
packages/pkg_binary.png
packages/pkg_compile.png
packages/pkg_conflict.png
packages/pkg_files.png
packages/pkg_include.png
packages/pkg_issues.png
packages/pkg_lfm.png
packages/pkg_lrs.png
packages/pkg_package_autoinstall.png
packages/pkg_package_circle.png
packages/pkg_package_uninstall.png
packages/pkg_registerunit.png
packages/pkg_removedfiles.png
packages/pkg_removedrequired.png
packages/pkg_text.png
packages/pkg_unit.png
packages/pkg_hierarchical.png
packages/pkg_sortalphabetically.png
codetoolsdefines/da_block.png codetoolsdefines/da_block.png
codetoolsdefines/da_define.png codetoolsdefines/da_define.png
codetoolsdefines/da_definerecurse.png codetoolsdefines/da_definerecurse.png
@ -242,5 +216,36 @@ codetoolsdefines/da_ifndef.png
codetoolsdefines/da_undefine.png codetoolsdefines/da_undefine.png
codetoolsdefines/da_undefineall.png codetoolsdefines/da_undefineall.png
codetoolsdefines/da_undefinerecurse.png codetoolsdefines/da_undefinerecurse.png
packages/pkg_properties.png
packages/pkg_design_overlay.png
packages/pkg_include.png
packages/pkg_removedrequired.png
packages/pkg_conflict.png
packages/pkg_binary.png
packages/pkg_core_overlay.png
packages/pkg_hierarchical.png
packages/pkg_registerunit.png
packages/pkg_sortalphabetically.png
packages/pkg_installed.png
packages/pkg_fpc_overlay.png
packages/pkg_issues.png
packages/pkg_removedfiles.png
packages/pkg_package_uninstall.png
packages/pkg_required.png
packages/pkg_lfm.png
packages/pkg_compile.png
packages/pkg_install.png
packages/pkg_graph.png
packages/pkg_lazarus_overlay.png
packages/pkg_text.png
packages/pkg_open.png
packages/pkg_package_circle.png
packages/pkg_runtime_overlay.png
packages/pkg_lrs.png
packages/pkg_inherited.png
packages/pkg_files.png
packages/pkg_unit.png
packages/pkg_package_autoinstall.png
packages/pkg_add.png
ide_icon48x48.png ide_icon48x48.png

View File

@ -21,8 +21,8 @@ object InstallPkgSetDialog: TInstallPkgSetDialog
AnchorSideRight.Control = lblMiddle AnchorSideRight.Control = lblMiddle
AnchorSideBottom.Control = PkgInfoGroupBox AnchorSideBottom.Control = PkgInfoGroupBox
Left = 6 Left = 6
Height = 401 Height = 362
Top = 28 Top = 27
Width = 284 Width = 284
Anchors = [akTop, akLeft, akRight, akBottom] Anchors = [akTop, akLeft, akRight, akBottom]
BorderSpacing.Left = 6 BorderSpacing.Left = 6
@ -30,14 +30,14 @@ object InstallPkgSetDialog: TInstallPkgSetDialog
BorderSpacing.Right = 3 BorderSpacing.Right = 3
BorderSpacing.Bottom = 6 BorderSpacing.Bottom = 6
Caption = 'InstallPkgGroupBox' Caption = 'InstallPkgGroupBox'
ClientHeight = 379 ClientHeight = 345
ClientWidth = 276 ClientWidth = 280
TabOrder = 0 TabOrder = 0
object ImportButton: TButton object ImportButton: TButton
Left = 6 Left = 6
Height = 25 Height = 25
Top = 317 Top = 283
Width = 264 Width = 268
Align = alBottom Align = alBottom
BorderSpacing.Around = 6 BorderSpacing.Around = 6
Caption = 'ImportButton' Caption = 'ImportButton'
@ -47,8 +47,8 @@ object InstallPkgSetDialog: TInstallPkgSetDialog
object ExportButton: TButton object ExportButton: TButton
Left = 6 Left = 6
Height = 25 Height = 25
Top = 348 Top = 314
Width = 264 Width = 268
Align = alBottom Align = alBottom
BorderSpacing.Around = 6 BorderSpacing.Around = 6
Caption = 'ExportButton' Caption = 'ExportButton'
@ -57,9 +57,9 @@ object InstallPkgSetDialog: TInstallPkgSetDialog
end end
object InstallTreeView: TTreeView object InstallTreeView: TTreeView
Left = 6 Left = 6
Height = 274 Height = 240
Top = 6 Top = 6
Width = 264 Width = 268
Align = alClient Align = alClient
BorderSpacing.Around = 6 BorderSpacing.Around = 6
DefaultItemHeight = 18 DefaultItemHeight = 18
@ -76,8 +76,8 @@ object InstallPkgSetDialog: TInstallPkgSetDialog
object UninstallButton: TBitBtn object UninstallButton: TBitBtn
Left = 6 Left = 6
Height = 25 Height = 25
Top = 286 Top = 252
Width = 264 Width = 268
Align = alBottom Align = alBottom
BorderSpacing.Around = 6 BorderSpacing.Around = 6
Caption = 'UninstallButton' Caption = 'UninstallButton'
@ -93,8 +93,8 @@ object InstallPkgSetDialog: TInstallPkgSetDialog
AnchorSideRight.Side = asrBottom AnchorSideRight.Side = asrBottom
AnchorSideBottom.Control = PkgInfoGroupBox AnchorSideBottom.Control = PkgInfoGroupBox
Left = 296 Left = 296
Height = 401 Height = 362
Top = 28 Top = 27
Width = 285 Width = 285
Anchors = [akTop, akLeft, akRight, akBottom] Anchors = [akTop, akLeft, akRight, akBottom]
BorderSpacing.Left = 3 BorderSpacing.Left = 3
@ -102,14 +102,16 @@ object InstallPkgSetDialog: TInstallPkgSetDialog
BorderSpacing.Right = 6 BorderSpacing.Right = 6
BorderSpacing.Bottom = 6 BorderSpacing.Bottom = 6
Caption = 'AvailablePkgGroupBox' Caption = 'AvailablePkgGroupBox'
ClientHeight = 379 ClientHeight = 345
ClientWidth = 277 ClientWidth = 281
TabOrder = 1 TabOrder = 1
object AvailableTreeView: TTreeView object AvailableTreeView: TTreeView
AnchorSideTop.Control = AvailableFilterEdit
AnchorSideTop.Side = asrBottom
Left = 6 Left = 6
Height = 311 Height = 276
Top = 31 Top = 32
Width = 265 Width = 269
Anchors = [akTop, akLeft, akRight, akBottom] Anchors = [akTop, akLeft, akRight, akBottom]
BorderSpacing.Left = 6 BorderSpacing.Left = 6
BorderSpacing.Right = 6 BorderSpacing.Right = 6
@ -129,8 +131,8 @@ object InstallPkgSetDialog: TInstallPkgSetDialog
object AddToInstallButton: TBitBtn object AddToInstallButton: TBitBtn
Left = 6 Left = 6
Height = 25 Height = 25
Top = 348 Top = 314
Width = 265 Width = 269
Align = alBottom Align = alBottom
BorderSpacing.Around = 6 BorderSpacing.Around = 6
Caption = 'AddToInstallButton' Caption = 'AddToInstallButton'
@ -139,9 +141,9 @@ object InstallPkgSetDialog: TInstallPkgSetDialog
end end
object AvailableFilterEdit: TTreeFilterEdit object AvailableFilterEdit: TTreeFilterEdit
Left = 6 Left = 6
Height = 22 Height = 25
Top = 7 Top = 7
Width = 243 Width = 247
UseFormActivate = True UseFormActivate = True
ButtonWidth = 23 ButtonWidth = 23
NumGlyphs = 1 NumGlyphs = 1
@ -156,19 +158,19 @@ object InstallPkgSetDialog: TInstallPkgSetDialog
object PkgInfoGroupBox: TGroupBox object PkgInfoGroupBox: TGroupBox
AnchorSideBottom.Control = BtnPanel AnchorSideBottom.Control = BtnPanel
Left = 0 Left = 0
Height = 93 Height = 127
Top = 435 Top = 395
Width = 587 Width = 587
Align = alBottom Align = alBottom
Caption = 'PkgInfoGroupBox' Caption = 'PkgInfoGroupBox'
ClientHeight = 71 ClientHeight = 110
ClientWidth = 579 ClientWidth = 583
TabOrder = 2 TabOrder = 2
object PkgInfoMemo: TMemo object PkgInfoMemo: TMemo
Left = 6 Left = 6
Height = 59 Height = 98
Top = 6 Top = 6
Width = 567 Width = 571
Align = alClient Align = alClient
BorderSpacing.Around = 6 BorderSpacing.Around = 6
ReadOnly = True ReadOnly = True
@ -178,20 +180,20 @@ object InstallPkgSetDialog: TInstallPkgSetDialog
end end
object BtnPanel: TPanel object BtnPanel: TPanel
Left = 0 Left = 0
Height = 34 Height = 40
Top = 528 Top = 522
Width = 587 Width = 587
Align = alBottom Align = alBottom
AutoSize = True AutoSize = True
BevelOuter = bvNone BevelOuter = bvNone
ClientHeight = 34 ClientHeight = 40
ClientWidth = 587 ClientWidth = 587
TabOrder = 3 TabOrder = 3
object HelpButton: TBitBtn object HelpButton: TBitBtn
Left = 6 Left = 6
Height = 22 Height = 28
Top = 6 Top = 6
Width = 78 Width = 75
Align = alLeft Align = alLeft
AutoSize = True AutoSize = True
BorderSpacing.Around = 6 BorderSpacing.Around = 6
@ -202,10 +204,10 @@ object InstallPkgSetDialog: TInstallPkgSetDialog
TabOrder = 0 TabOrder = 0
end end
object CancelButton: TBitBtn object CancelButton: TBitBtn
Left = 118 Left = 197
Height = 22 Height = 28
Top = 6 Top = 6
Width = 91 Width = 75
Align = alRight Align = alRight
AutoSize = True AutoSize = True
BorderSpacing.Around = 6 BorderSpacing.Around = 6
@ -217,10 +219,10 @@ object InstallPkgSetDialog: TInstallPkgSetDialog
TabOrder = 1 TabOrder = 1
end end
object SaveAndExitButton: TBitBtn object SaveAndExitButton: TBitBtn
Left = 413 Left = 443
Height = 22 Height = 28
Top = 6 Top = 6
Width = 168 Width = 138
Align = alRight Align = alRight
AutoSize = True AutoSize = True
BorderSpacing.Around = 6 BorderSpacing.Around = 6
@ -266,10 +268,10 @@ object InstallPkgSetDialog: TInstallPkgSetDialog
TabOrder = 2 TabOrder = 2
end end
object SaveAndRebuildButton: TBitBtn object SaveAndRebuildButton: TBitBtn
Left = 215 Left = 278
Height = 22 Height = 28
Top = 6 Top = 6
Width = 192 Width = 159
Align = alRight Align = alRight
AutoSize = True AutoSize = True
BorderSpacing.Around = 6 BorderSpacing.Around = 6
@ -317,7 +319,7 @@ object InstallPkgSetDialog: TInstallPkgSetDialog
end end
object NoteLabel: TLabel object NoteLabel: TLabel
Left = 6 Left = 6
Height = 16 Height = 15
Top = 6 Top = 6
Width = 575 Width = 575
Align = alTop Align = alTop

View File

@ -49,6 +49,25 @@ type
TOnCheckInstallPackageList = TOnCheckInstallPackageList =
procedure(PkgIDs: TObjectList; RemoveConflicts: boolean; out Ok: boolean) of object; procedure(PkgIDs: TObjectList; RemoveConflicts: boolean; out Ok: boolean) of object;
{ TIPSPkgInfo }
TIPSPkgInfo = class
public
ID: TLazPackageID;
LPKFilename: string;
InLazSrc: boolean; // lpk is in lazarus source directory
Installed: TPackageInstallType;
LPKParsed: boolean;
Author: string;
Description: string;
License: string;
PkgType: TLazPackageType; // design, runtime
constructor Create(TheID: TLazPackageID);
destructor Destroy; override;
end;
{ TInstallPkgSetDialog } { TInstallPkgSetDialog }
TInstallPkgSetDialog = class(TForm) TInstallPkgSetDialog = class(TForm)
@ -89,23 +108,28 @@ type
FNewInstalledPackages: TObjectList; // list of TLazPackageID (not TLazPackage) FNewInstalledPackages: TObjectList; // list of TLazPackageID (not TLazPackage)
FOldInstalledPackages: TPkgDependency; FOldInstalledPackages: TPkgDependency;
FOnCheckInstallPackageList: TOnCheckInstallPackageList; FOnCheckInstallPackageList: TOnCheckInstallPackageList;
fAvailablePackages: TAVLTree;// tree of TLazPackageID (all available packages and links) fAvailablePackages: TAVLTree;// tree of TIPSPkgInfo (all available packages and links)
FRebuildIDE: boolean; FRebuildIDE: boolean;
FSelectedPkg: TLazPackage; FSelectedPkg: TIPSPkgInfo;
ImgIndexPackage: integer; ImgIndexPackage: integer;
ImgIndexInstallPackage: integer; ImgIndexInstallPackage: integer;
ImgIndexInstalledPackage: integer; ImgIndexInstalledPackage: integer;
ImgIndexUninstallPackage: integer; ImgIndexUninstallPackage: integer;
ImgIndexCirclePackage: integer; ImgIndexCirclePackage: integer;
ImgIndexMissingPackage: integer; ImgIndexMissingPackage: integer;
ImgIndexOverlayBasePackage: integer;
ImgIndexOverlayFPCPackage: integer;
ImgIndexOverlayLazarusPackage: integer;
ImgIndexOverlayDesigntimePackage: integer;
ImgIndexOverlayRuntimePackage: integer;
procedure SetOldInstalledPackages(const AValue: TPkgDependency); procedure SetOldInstalledPackages(const AValue: TPkgDependency);
procedure AssignOldInstalledPackagesToList; procedure AssignOldInstalledPackagesToList;
function PackageInInstallList(PkgName: string): boolean; function PackageInInstallList(PkgName: string): boolean;
function GetPkgImgIndex(APackage: TLazPackage; InInstallList: boolean): integer; function GetPkgImgIndex(Installed: TPackageInstallType; InInstallList: boolean): integer;
function GetAvailablePkgImageIndex(Str: String; Data: TObject; var AIsEnabled: Boolean): Integer; function GetAvailablePkgImageIndex(Str: String; Data: TObject; var AIsEnabled: Boolean): Integer;
procedure UpdateAvailablePackages(Immediately: boolean = false); procedure UpdateAvailablePackages(Immediately: boolean = false);
procedure UpdateNewInstalledPackages; procedure UpdateNewInstalledPackages;
procedure OnIteratePackages(APackageID: TLazPackageID); procedure OnIterateAvailablePackages(APackageID: TLazPackageID);
function DependencyToStr(Dependency: TPkgDependency): string; function DependencyToStr(Dependency: TPkgDependency): string;
procedure ClearNewInstalledPackages; procedure ClearNewInstalledPackages;
function CheckSelection: boolean; function CheckSelection: boolean;
@ -119,11 +143,14 @@ type
function ExtractNameFromPkgID(ID: string): string; function ExtractNameFromPkgID(ID: string): string;
procedure AddToInstall; procedure AddToInstall;
procedure AddToUninstall; procedure AddToUninstall;
procedure ParseLPK(PkgInfo: TIPSPkgInfo; out Invalid, VersionChanged: boolean);
function FindPkgInfo(ID: string): TIPSPkgInfo;
function FindPkgInfo(PkgID: TLazPackageID): TIPSPkgInfo;
public public
function GetNewInstalledPackages: TObjectList; function GetNewInstalledPackages: TObjectList;
property OldInstalledPackages: TPkgDependency read FOldInstalledPackages property OldInstalledPackages: TPkgDependency read FOldInstalledPackages
write SetOldInstalledPackages; write SetOldInstalledPackages;
property NewInstalledPackages: TObjectList read FNewInstalledPackages; property NewInstalledPackages: TObjectList read FNewInstalledPackages; // list of TLazPackageID
property RebuildIDE: boolean read FRebuildIDE write FRebuildIDE; property RebuildIDE: boolean read FRebuildIDE write FRebuildIDE;
property OnCheckInstallPackageList: TOnCheckInstallPackageList property OnCheckInstallPackageList: TOnCheckInstallPackageList
read FOnCheckInstallPackageList write FOnCheckInstallPackageList; read FOnCheckInstallPackageList write FOnCheckInstallPackageList;
@ -134,6 +161,9 @@ function ShowEditInstallPkgsDialog(OldInstalledPackages: TPkgDependency;
var NewInstalledPackages: TObjectList; // list of TLazPackageID (must be freed) var NewInstalledPackages: TObjectList; // list of TLazPackageID (must be freed)
var RebuildIDE: boolean): TModalResult; var RebuildIDE: boolean): TModalResult;
function CompareIPSPkgInfos(PkgInfo1, PkgInfo2: Pointer): integer;
function ComparePkgIDWithIPSPkgInfo(PkgID, PkgInfo: Pointer): integer;
implementation implementation
{$R *.lfm} {$R *.lfm}
@ -160,6 +190,36 @@ begin
end; end;
end; end;
function CompareIPSPkgInfos(PkgInfo1, PkgInfo2: Pointer): integer;
var
Info1: TIPSPkgInfo absolute PkgInfo1;
Info2: TIPSPkgInfo absolute PkgInfo2;
begin
Result:=CompareLazPackageIDNames(Info1.ID,Info2.ID);
end;
function ComparePkgIDWithIPSPkgInfo(PkgID, PkgInfo: Pointer): integer;
var
ID: TLazPackageID absolute PkgID;
Info: TIPSPkgInfo absolute PkgInfo;
begin
Result:=CompareLazPackageIDNames(ID,Info.ID);
end;
{ TIPSPkgInfo }
constructor TIPSPkgInfo.Create(TheID: TLazPackageID);
begin
ID:=TLazPackageID.Create;
ID.AssignID(TheID);
end;
destructor TIPSPkgInfo.Destroy;
begin
FreeAndNil(ID);
inherited Destroy;
end;
{ TInstallPkgSetDialog } { TInstallPkgSetDialog }
procedure TInstallPkgSetDialog.InstallPkgSetDialogCreate(Sender: TObject); procedure TInstallPkgSetDialog.InstallPkgSetDialogCreate(Sender: TObject);
@ -172,6 +232,11 @@ begin
ImgIndexUninstallPackage := IDEImages.LoadImage(16, 'pkg_package_uninstall'); ImgIndexUninstallPackage := IDEImages.LoadImage(16, 'pkg_package_uninstall');
ImgIndexCirclePackage := IDEImages.LoadImage(16, 'pkg_package_circle'); ImgIndexCirclePackage := IDEImages.LoadImage(16, 'pkg_package_circle');
ImgIndexMissingPackage := IDEImages.LoadImage(16, 'pkg_conflict'); ImgIndexMissingPackage := IDEImages.LoadImage(16, 'pkg_conflict');
ImgIndexOverlayBasePackage := IDEImages.LoadImage(16, 'pkg_core_overlay');
ImgIndexOverlayFPCPackage := IDEImages.LoadImage(16, 'pkg_fpc_overlay');
ImgIndexOverlayLazarusPackage := IDEImages.LoadImage(16, 'pkg_lazarus_overlay');
ImgIndexOverlayDesignTimePackage := IDEImages.LoadImage(16, 'pkg_design_overlay');
ImgIndexOverlayRunTimePackage := IDEImages.LoadImage(16, 'pkg_runtime_overlay');
Caption:=lisInstallUninstallPackages; Caption:=lisInstallUninstallPackages;
NoteLabel.Caption:=lisToInstallYouMustCompileAndRestartTheIDE; NoteLabel.Caption:=lisToInstallYouMustCompileAndRestartTheIDE;
@ -192,7 +257,7 @@ begin
HelpButton.Caption:=lisMenuHelp; HelpButton.Caption:=lisMenuHelp;
CancelButton.Caption:=lisCancel; CancelButton.Caption:=lisCancel;
fAvailablePackages:=TAVLTree.Create(@CompareLazPackageIDNames); fAvailablePackages:=TAVLTree.Create(@CompareIPSPkgInfos);
FNewInstalledPackages:=TObjectList.Create(true); FNewInstalledPackages:=TObjectList.Create(true);
ActiveControl:=AvailableFilterEdit; ActiveControl:=AvailableFilterEdit;
PkgInfoMemo.Clear; PkgInfoMemo.Clear;
@ -286,8 +351,9 @@ end;
procedure TInstallPkgSetDialog.InstallPkgSetDialogDestroy(Sender: TObject); procedure TInstallPkgSetDialog.InstallPkgSetDialogDestroy(Sender: TObject);
begin begin
ClearNewInstalledPackages; ClearNewInstalledPackages;
FNewInstalledPackages.Free; FreeAndNil(FNewInstalledPackages);
fAvailablePackages.Free; fAvailablePackages.FreeAndClear;
FreeAndNil(fAvailablePackages);
end; end;
procedure TInstallPkgSetDialog.InstallPkgSetDialogResize(Sender: TObject); procedure TInstallPkgSetDialog.InstallPkgSetDialogResize(Sender: TObject);
@ -363,10 +429,10 @@ begin
Result:=false; Result:=false;
end; end;
function TInstallPkgSetDialog.GetPkgImgIndex(APackage: TLazPackage; function TInstallPkgSetDialog.GetPkgImgIndex(Installed: TPackageInstallType;
InInstallList: boolean): integer; InInstallList: boolean): integer;
begin begin
if APackage.Installed<>pitNope then begin if Installed<>pitNope then begin
// is not currently installed // is not currently installed
if InInstallList then begin if InInstallList then begin
// is installed and will be installed // is installed and will be installed
@ -391,45 +457,37 @@ end;
function TInstallPkgSetDialog.GetAvailablePkgImageIndex(Str: String; Data: TObject; function TInstallPkgSetDialog.GetAvailablePkgImageIndex(Str: String; Data: TObject;
var AIsEnabled: Boolean): Integer; var AIsEnabled: Boolean): Integer;
var
PkgInfo: TIPSPkgInfo;
begin begin
Result:=ImgIndexPackage; Result:=ImgIndexPackage;
if (Data is TLazPackage) then PkgInfo:=FindPkgInfo(Str);
Result:=GetPkgImgIndex(TLazPackage(Data),false); if PkgInfo<>nil then
Result:=GetPkgImgIndex(PkgInfo.Installed,false);
end; end;
procedure TInstallPkgSetDialog.UpdateAvailablePackages(Immediately: boolean); procedure TInstallPkgSetDialog.UpdateAvailablePackages(Immediately: boolean);
var var
ANode: TAVLTreeNode; ANode: TAVLTreeNode;
Pkg: TLazPackageID;
PkgName: String;
DuplCheck: TStringList; // Add pkg names also here to filter out duplicates.
FilteredBranch: TTreeFilterBranch; FilteredBranch: TTreeFilterBranch;
Info: TIPSPkgInfo;
begin begin
DuplCheck:=TStringList.Create; if fAvailablePackages.Count=0 then
try PackageGraph.IteratePackages(fpfSearchAllExisting,@OnIterateAvailablePackages);
if fAvailablePackages.Count=0 then FilteredBranch := AvailableFilterEdit.GetBranch(Nil); // All items are top level.
PackageGraph.IteratePackages(fpfSearchAllExisting,@OnIteratePackages); ANode:=fAvailablePackages.FindLowest;
FilteredBranch := AvailableFilterEdit.GetBranch(Nil); // All items are top level. while ANode<>nil do begin
ANode:=fAvailablePackages.FindLowest; Info:=TIPSPkgInfo(ANode.Data);
while ANode<>nil do begin if (not Info.LPKParsed)
Pkg:=TLazPackageID(ANode.Data); or (Info.PkgType in [lptDesignTime,lptRunAndDesignTime])
if (not (Pkg is TLazPackage)) then begin
or (TLazPackage(Pkg).PackageType in [lptDesignTime,lptRunAndDesignTime]) if (not PackageInInstallList(Info.ID.Name)) then begin
then begin FilteredBranch.AddNodeData(Info.ID.Name,nil);
if (not PackageInInstallList(Pkg.Name)) then begin
PkgName:=Pkg.IDAsString;
if (DuplCheck.IndexOf(PkgName)<0) then begin
DuplCheck.Add(PkgName);
FilteredBranch.AddNodeData(PkgName, Pkg);
end;
end;
end; end;
ANode:=fAvailablePackages.FindSuccessor(ANode);
end; end;
AvailableFilterEdit.InvalidateFilter; ANode:=fAvailablePackages.FindSuccessor(ANode);
finally
DuplCheck.Free;
end; end;
AvailableFilterEdit.InvalidateFilter;
end; end;
procedure TInstallPkgSetDialog.UpdateNewInstalledPackages; procedure TInstallPkgSetDialog.UpdateNewInstalledPackages;
@ -460,7 +518,7 @@ begin
ImgIndex:=ImgIndexInstallPackage; ImgIndex:=ImgIndexInstallPackage;
if NewPackageID is TLazPackage then begin if NewPackageID is TLazPackage then begin
APackage:=TLazPackage(NewPackageID); APackage:=TLazPackage(NewPackageID);
ImgIndex:=GetPkgImgIndex(APackage,true); ImgIndex:=GetPkgImgIndex(APackage.Installed,true);
end; end;
TVNode.ImageIndex:=ImgIndex; TVNode.ImageIndex:=ImgIndex;
TVNode.SelectedIndex:=ImgIndex; TVNode.SelectedIndex:=ImgIndex;
@ -470,11 +528,53 @@ begin
UpdateAvailablePackages; UpdateAvailablePackages;
end; end;
procedure TInstallPkgSetDialog.OnIteratePackages(APackageID: TLazPackageID); procedure TInstallPkgSetDialog.OnIterateAvailablePackages(APackageID: TLazPackageID);
var
Info: TIPSPkgInfo;
Pkg: TLazPackage;
OldInfo: TIPSPkgInfo;
Link: TPackageLink;
begin begin
//debugln('TInstallPkgSetDialog.OnIteratePackages ',APackageID.IDAsString); //debugln('TInstallPkgSetDialog.OnIteratePackages ',APackageID.IDAsString);
if (fAvailablePackages.Find(APackageID)=nil) then if APackageID=nil then exit;
fAvailablePackages.Add(APackageID); OldInfo:=FindPkgInfo(APackageID);
if (OldInfo<>nil) and OldInfo.LPKParsed then begin
// old is good enough => ignore duplicate
exit;
end;
if APackageID is TLazPackage then begin
// a loaded package
Pkg:=TLazPackage(APackageID);
Info:=TIPSPkgInfo.Create(APackageID);
Info.LPKFilename:=Pkg.Filename;
Info.LPKParsed:=true;
Info.Installed:=Pkg.Installed;
Info.PkgType:=Pkg.PackageType;
Info.Author:=Pkg.Author;
Info.Description:=Pkg.Description;
Info.License:=Pkg.License;
end else if APackageID is TPackageLink then begin
// only a link to a package
Link:=TPackageLink(APackageID);
Info:=TIPSPkgInfo.Create(APackageID);
Info.LPKFilename:=Link.GetEffectiveFilename;
end else
exit;
Info.InLazSrc:=FileIsInPath(Info.LPKFilename,EnvironmentOptions.GetParsedLazarusDirectory);
if OldInfo<>nil then begin
if Info.LPKParsed
or (not FileExistsCached(OldInfo.LPKFilename)) then begin
// the new info is better => remove old
fAvailablePackages.Remove(OldInfo);
OldInfo.Free;
end else begin
Info.Free;
exit;
end;
end;
fAvailablePackages.Add(Info);
end; end;
function TInstallPkgSetDialog.DependencyToStr(Dependency: TPkgDependency): string; function TInstallPkgSetDialog.DependencyToStr(Dependency: TPkgDependency): string;
@ -538,72 +638,44 @@ var
end; end;
var var
PkgName: String; PkgID: String;
PkgID: TLazPackageID; Invalid: boolean;
Author: String; VersionChanged: boolean;
Description: String;
PkgLink: TPackageLink;
XMLConfig: TXMLConfig;
begin begin
if Tree = nil then Exit; if Tree = nil then Exit;
PkgName := ''; PkgID := '';
if Tree.Selected <> nil then if Tree.Selected <> nil then
PkgName := Tree.Selected.Text; PkgID := Tree.Selected.Text;
if PkgID = '' then Exit;
if PkgName = '' then Exit; if Assigned(FSelectedPkg) and (PkgID = FSelectedPkg.ID.IDAsString) then
if Assigned(FSelectedPkg) and (PkgName = FSelectedPkg.IDAsString) then Exit; exit;
PkgInfoMemo.Clear; PkgInfoMemo.Clear;
PkgID := TLazPackageID.Create;
try
PkgID.StringToID(PkgName);
FSelectedPkg := PackageGraph.FindPackageWithID(PkgID);
Author:=''; FSelectedPkg:=FindPkgInfo(PkgID);
Description:=''; if FSelectedPkg=nil then exit;
if FSelectedPkg <> nil then begin
Author:=FSelectedPkg.Author; if not FSelectedPkg.LPKParsed then begin
Description:=FSelectedPkg.Description; ParseLPK(FSelectedPkg,Invalid,VersionChanged);
end else begin if Invalid then
// package not loaded -> read values from .lpk exit;
PkgLink:=PkgLinks.FindLinkWithPackageID(PkgID);
if (PkgLink<>nil) and FileExistsCached(PkgLink.GetEffectiveFilename) then begin
// load the package file
try
XMLConfig:=TXMLConfig.Create(PkgLink.GetEffectiveFilename);
try
Author:=XMLConfig.GetValue('Package/Author/Value','');
Description:=XMLConfig.GetValue('Package/Description/Value','');
finally
XMLConfig.Free;
end;
except
on E: Exception do begin
DebugLn('TInstallPkgSetDialog.UpdatePackageInfo ERROR: ',E.Message);
end;
end;
end;
end;
if Author<>'' then
PkgInfoMemo.Lines.Add(lisPckOptsAuthor + ': ' + Author);
if Description<>'' then
PkgInfoMemo.Lines.Add(lisPckOptsDescriptionAbstract
+ ': ' + Description);
if FSelectedPkg<>nil then
begin
PkgInfoMemo.Lines.Add(Format(lisOIPFilename, [FSelectedPkg.Filename]));
InfoStr:=lisCurrentState;
if FSelectedPkg.Installed<>pitNope then
AddState(lisInstalled)
else
AddState(lisNotInstalled);
if FSelectedPkg.AutoCreated then
AddState(lisPckExplAutoCreated);
PkgInfoMemo.Lines.Add(InfoStr);
end;
finally
PkgId.Free;
end; end;
if FSelectedPkg.Author<>'' then
PkgInfoMemo.Lines.Add(lisPckOptsAuthor + ': ' + FSelectedPkg.Author);
if FSelectedPkg.Description<>'' then
PkgInfoMemo.Lines.Add(lisPckOptsDescriptionAbstract
+ ': ' + FSelectedPkg.Description);
PkgInfoMemo.Lines.Add(Format(lisOIPFilename, [FSelectedPkg.LPKFilename]));
InfoStr:=lisCurrentState;
if FSelectedPkg.Installed<>pitNope then
AddState(lisInstalled)
else
AddState(lisNotInstalled);
if PackageGraph.IsStaticBasePackage(FSelectedPkg.ID.Name) then
AddState(lisPckExplBase);
AddState(LazPackageTypeIdents[FSelectedPkg.PkgType]);
PkgInfoMemo.Lines.Add(InfoStr);
end; end;
function TInstallPkgSetDialog.NewInstalledPackagesContains( function TInstallPkgSetDialog.NewInstalledPackagesContains(
@ -884,6 +956,80 @@ begin
end; end;
end; end;
procedure TInstallPkgSetDialog.ParseLPK(PkgInfo: TIPSPkgInfo; out Invalid,
VersionChanged: boolean);
var
XMLConfig: TXMLConfig;
Path: String;
FileVersion: Integer;
NewVersion: TPkgVersion;
begin
VersionChanged:=false;
Invalid:=false;
if (PkgInfo=nil) or (PkgInfo.LPKParsed) then exit;
if FileExistsCached(PkgInfo.LPKFilename) then begin
// load the package file
try
XMLConfig:=TXMLConfig.Create(PkgInfo.LPKFilename);
NewVersion:=TPkgVersion.Create;
try
Path:='Package/';
FileVersion:=XMLConfig.GetValue(Path+'Version',0);
PkgInfo.Author:=XMLConfig.GetValue(Path+'Author/Value','');
PkgInfo.Description:=XMLConfig.GetValue(Path+'Description/Value','');
PkgInfo.License:=XMLConfig.GetValue(Path+'License/Value','');
PkgInfo.PkgType:=LazPackageTypeIdentToType(XMLConfig.GetValue(Path+'Type/Value',
LazPackageTypeIdents[lptRunTime]));
PkgVersionLoadFromXMLConfig(NewVersion,XMLConfig,Path+'Version/',FileVersion);
if PkgInfo.ID.Version.Compare(NewVersion)<>0 then begin
VersionChanged:=true;
fAvailablePackages.Remove(PkgInfo);
PkgInfo.ID.Version.Assign(NewVersion);
fAvailablePackages.Add(PkgInfo);
end;
finally
NewVersion.Free;
XMLConfig.Free;
end;
except
on E: Exception do begin
DebugLn('TInstallPkgSetDialog.ParseLPK ERROR: file="'+PkgInfo.LPKFilename+'": '+E.Message);
Invalid:=true;
end;
end;
end else begin
Invalid:=true;
end;
if Invalid then begin
if PkgInfo=FSelectedPkg then FSelectedPkg:=nil;
fAvailablePackages.Remove(PkgInfo);
PkgInfo.Free;
end;
end;
function TInstallPkgSetDialog.FindPkgInfo(ID: string): TIPSPkgInfo;
var
PkgID: TLazPackageID;
begin
Result:=nil;
PkgID:=TLazPackageID.Create;
try
if not PkgID.StringToID(ID) then exit;
Result:=FindPkgInfo(PkgID);
finally
PkgID.Free;
end;
end;
function TInstallPkgSetDialog.FindPkgInfo(PkgID: TLazPackageID): TIPSPkgInfo;
var
Node: TAVLTreeNode;
begin
Node:=fAvailablePackages.FindKey(PkgID,@ComparePkgIDWithIPSPkgInfo);
if Node=nil then exit(nil);
Result:=TIPSPkgInfo(Node.Data);
end;
function TInstallPkgSetDialog.GetNewInstalledPackages: TObjectList; function TInstallPkgSetDialog.GetNewInstalledPackages: TObjectList;
var var
i: Integer; i: Integer;