From 31b7c271817c7ee0df97e91b8f6fcb90152ee177 Mon Sep 17 00:00:00 2001 From: balazs Date: Mon, 18 Dec 2017 13:39:12 +0000 Subject: [PATCH] IDE: Installpkgsetdlg dialog: Display online packages when OPM is installed. git-svn-id: trunk@56778 - --- components/ideintf/packagelinkintf.pas | 14 ++- ide/lazarusidestrconsts.pas | 6 +- packager/installpkgsetdlg.pas | 144 ++++++++++++++++++++++--- packager/lpkcache.pas | 11 +- packager/packagelinks.pas | 2 +- 5 files changed, 153 insertions(+), 24 deletions(-) diff --git a/components/ideintf/packagelinkintf.pas b/components/ideintf/packagelinkintf.pas index 4486352edb..f9bbf5c87f 100644 --- a/components/ideintf/packagelinkintf.pas +++ b/components/ideintf/packagelinkintf.pas @@ -63,8 +63,11 @@ type FPackageType: TLazPackageType; FOrigin: TPkgLinkOrigin; FLastUsed: TDateTime; - FOPMFileName: String; + FOPMFileName: string; FOPMFileDate: TDateTime; + FAuthor: string; + FDescription: string; + FLicense: string; public constructor Create; override; destructor Destroy; override; @@ -80,11 +83,14 @@ type property LPKUrl: string read FURL write FURL; property LPLFilename: string read FLPLFilename write FLPLFilename; property LPLFileDate: TDateTime read FLPLFileDate write FLPLFileDate; - property PackageType: TLazPackageType read FPackageType; + property PackageType: TLazPackageType read FPackageType write FPackageType; property Origin: TPkgLinkOrigin read FOrigin write FOrigin; property LastUsed: TDateTime read FLastUsed write FLastUsed; property OPMFileName: string read FOPMFileName write FOPMFileName; property OPMFileDate: TDateTime read FOPMFileDate write FOPMFileDate; + property Author: string read FAuthor write FAuthor; + property Description: string read FDescription write FDescription; + property License: string read FLicense write FLicense; end; { TPackageLinks } @@ -105,6 +111,7 @@ type procedure RemoveUserLink(Link: TPackageLink); virtual; abstract; procedure RemoveUserLinks(APackageID: TLazPackageID); virtual; abstract; procedure ClearOnlineLinks; virtual; abstract; + procedure SaveUserLinks(Immediately: boolean = false); virtual; abstract; end; { TOPMInterface } @@ -114,7 +121,10 @@ type FPackageListAvailable: TNotifyEvent; public {confirmation/install/extract/download dialogs will be displayed in the center of WorkArea} + function DownloadPackages(APkgLinks: TList): TModalResult; virtual; abstract; function InstallPackages(APkgLinks: TList; var ANeedToRebuild: Boolean): TModalResult; virtual; abstract; + function IsPackageAvailable(APkgLink: TPackageLink; AType: Integer): Boolean; virtual; abstract; + function FindOnlineLink(const AName: String): TPackageLink; virtual; abstract; property OnPackageListAvailable: TNotifyEvent read FPackageListAvailable write FPackageListAvailable; end; diff --git a/ide/lazarusidestrconsts.pas b/ide/lazarusidestrconsts.pas index 00b7944609..d38c5ed3a3 100644 --- a/ide/lazarusidestrconsts.pas +++ b/ide/lazarusidestrconsts.pas @@ -3576,6 +3576,9 @@ resourcestring lisThePackageIsAlreadyInTheList = 'The package %s is already in the list'; lisConflict = 'Conflict'; lisThereIsAlreadyAPackageInTheList = 'There is already a package %s in the list'; + lisDownload = 'Download'; + lisDonwloadOnlinePackages = 'The following package(s) are not available locally: %s .' + sLineBreak + + 'In order to install it, you must download them first. Download now?'; lisNotADesigntimePackage = 'Not a designtime package'; lisThePackageCanNotBeInstalledBecauseItRequiresWhichI = 'The package %s cannot be ' +'installed, because it requires the package "%s", which is a runtime only package.'; @@ -4307,7 +4310,7 @@ resourcestring lisPkgMangTheFollowingPackagesFailedToLoad = 'The following packages failed to load:'; lisMissingPackages = 'Missing Packages'; lisNotInstalledPackages = 'Not installed packages'; - lisInstallPackagesMsg = 'The following packages are not installed, but available online: %s.' + + lisInstallPackagesMsg = 'The following packages are not installed, but available in the main repository: %s.' + sLineBreak + 'Do you wish to install missing packages?'; lisOtherSourcesPathOfPackageContainsDirectoryWhichIsA = 'other sources path ' +'of package "%s" contains directory "%s", which is already in the unit ' @@ -4537,6 +4540,7 @@ resourcestring lisSelectedForUninstallation = 'selected for uninstallation'; lisInstalled = 'installed'; lisNotInstalled = 'not installed'; + lisOnlinePackage = 'available in the main repository'; lisOIPThisPackageIsInstalledButTheLpkFileWasNotFound = '%sThis package is ' +'installed, but the lpk file was not found'; lisOIPDescriptionDescription = '%sDescription: %s'; diff --git a/packager/installpkgsetdlg.pas b/packager/installpkgsetdlg.pas index 02ec606a0f..bcb86c4e0b 100644 --- a/packager/installpkgsetdlg.pas +++ b/packager/installpkgsetdlg.pas @@ -48,9 +48,9 @@ uses // LazUtils LazFileUtils, Laz2_XMLCfg, // IdeIntf - PackageDependencyIntf, PackageIntf, IDEImagesIntf, IDEHelpIntf, IDEDialogs, IDEWindowIntf, + PackageDependencyIntf, PackageIntf, IDEImagesIntf, IDEHelpIntf, IDEDialogs, IDEWindowIntf, PackageLinkIntf, // IDE - LazarusIDEStrConsts, InputHistory, LazConf, PackageDefs, PackageSystem, LPKCache; + LazarusIDEStrConsts, InputHistory, LazConf, PackageDefs, PackageSystem, LPKCache, PackageLinks; type TOnCheckInstallPackageList = @@ -120,6 +120,7 @@ type ImgIndexUninstallPackage: integer; ImgIndexCirclePackage: integer; ImgIndexMissingPackage: integer; + ImgIndexAvailableOnline: integer; ImgIndexOverlayUnknown: integer; ImgIndexOverlayBasePackage: integer; ImgIndexOverlayFPCPackage: integer; @@ -130,7 +131,8 @@ type procedure SetOldInstalledPackages(const AValue: TPkgDependency); procedure AssignOldInstalledPackagesToList; function PackageInInstallList(PkgName: string): boolean; - function GetPkgImgIndex(Installed: TPackageInstallType; InInstallList: boolean): integer; + function GetPkgImgIndex(Installed: TPackageInstallType; InInstallList, + IsOnline: boolean): integer; procedure UpdateAvailablePackages(Immediately: boolean = false); procedure UpdateNewInstalledPackages; function DependencyToStr(Dependency: TPkgDependency): string; @@ -148,6 +150,7 @@ type procedure AddToUninstall; procedure PkgInfosChanged; procedure ChangePkgVersion(PkgInfo: TLPKInfo; NewVersion: TPkgVersion); + function FindOnlinePackageLink(const AName: String): TPackageLink; public function GetNewInstalledPackages: TObjectList; property OldInstalledPackages: TPkgDependency read FOldInstalledPackages @@ -203,6 +206,7 @@ begin ImgIndexUninstallPackage := IDEImages.LoadImage('pkg_package_uninstall'); ImgIndexCirclePackage := IDEImages.LoadImage('pkg_package_circle'); ImgIndexMissingPackage := IDEImages.LoadImage('pkg_conflict'); + ImgIndexAvailableOnline := IDEImages.LoadImage('pkg_install'); ImgIndexOverlayUnknown := IDEImages.LoadImage('state_unknown'); ImgIndexOverlayBasePackage := IDEImages.LoadImage('pkg_core_overlay'); ImgIndexOverlayFPCPackage := IDEImages.LoadImage('pkg_fpc_overlay'); @@ -381,6 +385,7 @@ var PkgName: String; ImgIndex: Integer; Unknown: Boolean; + PackageLink: TPackageLink; begin Tree:=Sender as TTreeView; if Stage=cdPostPaint then begin @@ -397,6 +402,10 @@ begin finally LPKInfoCache.LeaveCritSection; end; + if Sender = InstallTreeView then + PackageLink := nil + else + PackageLink := FindOnlinePackageLink(Info.ID.Name); Images:=Tree.Images; CurCanvas:=Tree.Canvas; @@ -404,7 +413,7 @@ begin x:=Node.DisplayIconLeft+1; y:=(NodeRect.Top+NodeRect.Bottom-Images.Height) div 2; // draw image - ImgIndex:=GetPkgImgIndex(Installed,PackageInInstallList(PkgName)); + ImgIndex:=GetPkgImgIndex(Installed,PackageInInstallList(PkgName), PackageLink <> nil); Images.Draw(CurCanvas,x,y,ImgIndex); // draw overlays if InLazSrc then @@ -513,7 +522,7 @@ begin end; function TInstallPkgSetDialog.GetPkgImgIndex(Installed: TPackageInstallType; - InInstallList: boolean): integer; + InInstallList, IsOnline: boolean): integer; begin if Installed<>pitNope then begin // is not currently installed @@ -533,11 +542,33 @@ begin end else begin // is not installed and will be not be installed - Result:=ImgIndexPackage; + if IsOnline then + Result := ImgIndexAvailableOnline + else + Result:=ImgIndexPackage; end; end; end; +function TInstallPkgSetDialog.FindOnlinePackageLink(const AName: String): TPackageLink; +var + PackageLink: TPackageLink; + PkgName: String; + P: Integer; +begin + Result := nil; + if OPMInterface = nil then + Exit; + PkgName := Trim(AName); + P := Pos(' ', PkgName); + if P > 0 then + PkgName := Copy(PkgName, 1, P - 1); + PackageLink := OPMInterface.FindOnlineLink(PkgName); + if PackageLink <> nil then + Result := PackageLink; +end; + + procedure TInstallPkgSetDialog.UpdateAvailablePackages(Immediately: boolean); var ANode: TAvlTreeNode; @@ -545,6 +576,7 @@ var Info: TLPKInfo; List: TStringList; i: Integer; + PackageLink: TPackageLink; begin if not Immediately then begin fAvailablePkgsNeedUpdate:=true; @@ -561,6 +593,15 @@ begin while ANode<>nil do begin Info:=TLPKInfo(ANode.Data); ANode:=LPKInfoCache.LPKByID.FindSuccessor(ANode); + PackageLink := FindOnlinePackageLink(Info.ID.Name); + if (PackageLink <> nil) and (PackageLink.PackageType in [lptDesignTime,lptRunAndDesignTime]) then begin + if (not PackageInInstallList(Info.ID.Name)) then begin + Info.PkgType := PackageLink.PackageType; + Info.ID.Version.Assign(PackageLink.Version); + List.Add(Info.ID.IDAsString); + Continue; + end; + end; if Info.LPKParsed=lpkiParsedError then continue; if (Info.LPKParsed in [lpkiNotParsed,lpkiParsing]) or (Info.PkgType in [lptDesignTime,lptRunAndDesignTime]) @@ -704,13 +745,18 @@ var var PkgID: String; Info: TLPKInfo; + PackageLink: TPackageLink; + Author, Description, License: String; begin if Tree = nil then Exit; PkgID := ''; if Tree.Selected <> nil then PkgID := Tree.Selected.Text; if PkgID = '' then Exit; - + if Tree = InstallTreeView then + PackageLink := nil + else + PackageLink := FindOnlinePackageLink(PkgID); LPKInfoCache.EnterCritSection; try Info:=LPKInfoCache.FindPkgInfoWithIDAsString(PkgID); @@ -735,13 +781,26 @@ begin end; end; - if Info.Author<>'' then - PkgInfoMemo.Lines.Add(lisPckOptsAuthor + ': ' + Info.Author); - if Info.Description<>'' then - PkgInfoMemo.Lines.Add(lisPckOptsDescriptionAbstract - + ': ' + Info.Description); - if Info.License<>'' then - PkgInfoMemo.Lines.Add(lisPckOptsLicense + ': ' + Info.License); + if PackageLink = nil then + begin + Author := Info.Author; + Description := Info.Description; + License := Info.License; + end + else + begin + Author := PackageLink.Author; + Description := PackageLink.Description; + License := PackageLink.License; + end; + + if Author<>'' then + PkgInfoMemo.Lines.Add(lisPckOptsAuthor + ': ' + Author); + if Description<>'' then + PkgInfoMemo.Lines.Add(lisPckOptsDescriptionAbstract + ': ' + Description); + if License<>'' then + PkgInfoMemo.Lines.Add(lisPckOptsLicense + ': ' + License); + PkgInfoMemo.Lines.Add(Format(lisOIPFilename, [Info.LPKFilename])); InfoStr:=lisCurrentState; @@ -756,6 +815,8 @@ begin if PackageInInstallList(Info.ID.Name)=true then AddState(lisSelectedForInstallation); AddState(lisNotInstalled); + if PackageLink <> nil then + AddState(lisOnlinePackage); end; if Info.Base then AddState(lisPckExplBase); @@ -954,11 +1015,15 @@ var TVNode: TTreeNode; PkgName: String; FilteredBranch: TTreeFilterBranch; + PkgLinks: TList; + PkgLinksStr: String; + PkgLink: TPackageLink; begin NewSelectedIndex:=-1; LastNonSelectedIndex:=-1; Additions:=TObjectList.Create(false); AddedPkgNames:=TStringList.Create; + PkgLinks := TList.Create; NewPackageID:=TLazPackageID.Create; FilteredBranch := AvailableFilterEdit.GetExistingBranch(Nil); // All items are top level. try @@ -982,9 +1047,53 @@ begin exit; end; // ok => add to list - Additions.Add(NewPackageID); - NewPackageID:=TLazPackageID.Create; - AddedPkgNames.Add(PkgName); + PkgLink := FindOnlinePackageLink(NewPackageID.Name); + if PkgLink <> nil then begin + if not FileExists(PkgLink.OPMFileName) then + PkgLinks.Add(PkgLink) + else + begin + PkgLink := LazPackageLinks.AddUserLink(PkgLink.OPMFileName, PkgLink.Name); + if PkgLink <> nil then + LazPackageLinks.SaveUserLinks; + Additions.Add(NewPackageID); + NewPackageID:=TLazPackageID.Create; + AddedPkgNames.Add(PkgName); + end; + end else begin + Additions.Add(NewPackageID); + NewPackageID:=TLazPackageID.Create; + AddedPkgNames.Add(PkgName); + end; + end; + //download online packages + if (OPMInterface <> nil) and (PkgLinks.Count > 0) then + begin + PkgLinksStr := ''; + for I := 0 to PkgLinks.Count - 1 do begin + if PkgLinksStr = '' then + PkgLinksStr := '"' + TPackageLink(PkgLinks.Items[I]).Name + '"' + else + PkgLinksStr := PkgLinksStr + ', ' + '"' + TPackageLink(PkgLinks.Items[I]).Name + '"'; + end; + if IDEMessageDialog(lisDownload, Format(lisDonwloadOnlinePackages, [PkgLinksStr]), mtConfirmation, [mbYes, mbNo]) = mrYes then begin + if OPMInterface.DownloadPackages(PkgLinks) = mrOK then begin + for I := PkgLinks.Count - 1 downto 0 do begin + if OPMInterface.IsPackageAvailable(TPackageLink(PkgLinks.Items[I]), 1) then begin + Additions.Add(NewPackageID); + NewPackageID:=TLazPackageID.Create; + AddedPkgNames.Add(PkgName); + PkgLink := LazPackageLinks.AddUserLink(TPackageLink(PkgLinks.Items[I]).OPMFileName, TPackageLink(PkgLinks.Items[I]).Name); + if PkgLink <> nil then + LazPackageLinks.SaveUserLinks; + end; + end; + end + else + Dec(NewSelectedIndex); + end + else + Dec(NewSelectedIndex); end; // all ok => add to installed packages for i:=0 to Additions.Count-1 do @@ -1006,6 +1115,7 @@ begin NewPackageID.Free; AddedPkgNames.Free; Additions.Free; + PkgLinks.Free; end; end; diff --git a/packager/lpkcache.pas b/packager/lpkcache.pas index 70d9ebd30a..cc77240069 100644 --- a/packager/lpkcache.pas +++ b/packager/lpkcache.pas @@ -57,7 +57,7 @@ uses // LazUtils LazFileUtils, Laz2_XMLCfg, LazLoggerBase, LazMethodList, // IdeIntf - PackageDependencyIntf, PackageIntf, + PackageDependencyIntf, PackageIntf, PackageLinkIntf, // IDE EnvironmentOpts, PackageLinks, PackageDefs, PackageSystem; @@ -357,8 +357,13 @@ procedure TLPKInfoCache.OnIterateAvailablePackages(APackage: TLazPackageID); begin if APackage is TLazPackage then fAvailableFiles.Add(TLazPackage(APackage).Filename) - else if APackage is TLazPackageLink then - fAvailableFiles.Add(TLazPackageLink(APackage).LPKFilename); + else if APackage is TLazPackageLink then begin + if (OPMInterface<>nil) and (TLazPackageLink(APackage).Origin=ploOnline) and + (not OPMInterface.IsPackageAvailable(TLazPackageLink(APackage), 2)) then + fAvailableFiles.Add(TLazPackageLink(APackage).OPMFileName) + else + fAvailableFiles.Add(TLazPackageLink(APackage).LPKFilename); + end; end; procedure TLPKInfoCache.QueueEmpty; diff --git a/packager/packagelinks.pas b/packager/packagelinks.pas index 0d7ca904f5..a867673f40 100644 --- a/packager/packagelinks.pas +++ b/packager/packagelinks.pas @@ -131,7 +131,7 @@ type procedure BeginUpdate; procedure EndUpdate; function IsUpdating: boolean; - procedure SaveUserLinks(Immediately: boolean = false); + procedure SaveUserLinks(Immediately: boolean = false); override; function NeedSaveUserLinks(const ConfigFilename: string): boolean; procedure WriteLinkTree(LinkTree: TAvlTree); procedure IncreaseChangeStamp;