diff --git a/packager/basepkgmanager.pas b/packager/basepkgmanager.pas index 69bd49cb0d..1edeea8faf 100644 --- a/packager/basepkgmanager.pas +++ b/packager/basepkgmanager.pas @@ -61,6 +61,7 @@ type TPkgCompileFlag = ( pcfCleanCompile, // append -B to the compiler options pcfDoNotCompileDependencies, + pcfCompileDependenciesClean, pcfOnlyIfNeeded, pcfDoNotSaveEditorFiles ); @@ -130,6 +131,7 @@ const PkgCompileFlagNames: array[TPkgCompileFlag] of string = ( 'pcfCleanCompile', 'pcfDoNotCompileDependencies', + 'pcfCompileDependenciesClean', 'pcfOnlyIfNeeded', 'pcfAutomatic' ); diff --git a/packager/packagedefs.pas b/packager/packagedefs.pas index dc934aaf6c..1eee5edcc6 100644 --- a/packager/packagedefs.pas +++ b/packager/packagedefs.pas @@ -391,8 +391,6 @@ type TLazPackageFlag = ( lpfAutoIncrementVersionOnBuild, // increment version before lpfModified, // package needs saving - lpfAutoUpdate, // auto compile, if this package - // or any required package has been modified lpfNeeded, // Set by PackageGraph, if package is in use // (for example because it is Installed or an Installed // package requires this package) @@ -405,24 +403,34 @@ type ); TLazPackageFlags = set of TLazPackageFlag; - TIterateComponentClassesEvent = - procedure(PkgComponent: TPkgComponent) of object; - TPackageInstallType = ( pitNope, pitStatic, pitDynamic ); + TPackageUpdatePolicy = ( + pupManually, + pupOnRebuildingAll, + pupAsNeeded + ); + TPackageUpdatePolicies = set of TPackageUpdatePolicy; + +const + pupAllAuto = [pupAsNeeded,pupOnRebuildingAll]; + +type + TIterateComponentClassesEvent = + procedure(PkgComponent: TPkgComponent) of object; TPkgChangeNameEvent = procedure(Pkg: TLazPackage; const OldName: string) of object; - + TLazPackage = class(TLazPackageID) private FAuthor: string; FAutoCreated: boolean; FAutoInstall: TPackageInstallType; - FBroken: boolean; + FAutoUpdate: TPackageUpdatePolicy; FCompilerOptions: TPkgCompilerOptions; FComponents: TList; // TList of TPkgComponent FDefineTemplates: TLazPackageDefineTemplates; @@ -442,6 +450,7 @@ type FLastCompilerParams: string; FLicense: string; FMacros: TTransferMacroList; + FMissing: boolean; FModifiedLock: integer; FOutputStateFile: string; FPackageEditor: TBasePackageEditor; @@ -454,7 +463,6 @@ type FUpdateLock: integer; FUsageOptions: TPkgAdditionalCompilerOptions; function GetAutoIncrementVersionOnBuild: boolean; - function GetAutoUpdate: boolean; function GetComponentCount: integer; function GetComponents(Index: integer): TPkgComponent; function GetRemovedCount: integer; @@ -466,7 +474,7 @@ type procedure SetAutoCreated(const AValue: boolean); procedure SetAutoIncrementVersionOnBuild(const AValue: boolean); procedure SetAutoInstall(const AValue: TPackageInstallType); - procedure SetAutoUpdate(const AValue: boolean); + procedure SetAutoUpdate(const AValue: TPackageUpdatePolicy); procedure SetDescription(const AValue: string); procedure SetFilename(const AValue: string); procedure SetFlags(const AValue: TLazPackageFlags); @@ -555,11 +563,13 @@ type property Author: string read FAuthor write SetAuthor; property AutoCreated: boolean read FAutoCreated write SetAutoCreated; property AutoIncrementVersionOnBuild: boolean - read GetAutoIncrementVersionOnBuild write SetAutoIncrementVersionOnBuild; + read GetAutoIncrementVersionOnBuild + write SetAutoIncrementVersionOnBuild; property AutoInstall: TPackageInstallType read FAutoInstall write SetAutoInstall; - property AutoUpdate: boolean read GetAutoUpdate write SetAutoUpdate; - property Broken: boolean read FBroken write FBroken; + property AutoUpdate: TPackageUpdatePolicy read FAutoUpdate + write SetAutoUpdate; + property Missing: boolean read FMissing write FMissing; property CompilerOptions: TPkgCompilerOptions read FCompilerOptions; property ComponentCount: integer read GetComponentCount; property Components[Index: integer]: TPkgComponent read GetComponents; @@ -629,9 +639,15 @@ const LazPackageTypeIdents: array[TLazPackageType] of string = ( 'RunTime', 'DesignTime', 'RunAndDesignTime'); LazPackageFlagNames: array[TLazPackageFlag] of string = ( - 'lpfAutoIncrementVersionOnBuild', 'lpfModified', 'lpfAutoUpdate', + 'lpfAutoIncrementVersionOnBuild', 'lpfModified', 'lpfNeeded', 'lpfVisited', 'lpfDestroying', 'lpfLoading', 'lpfSkipSaving', 'lpfCircle', 'lpfStateFileLoaded'); + PackageUpdatePolicies: array[TPackageUpdatePolicy] of string = ( + 'pupManually', 'pupOnRebuildingAll', 'pupAsNeeded' + ); + AutoUpdateNames: array[TPackageUpdatePolicy] of string = ( + 'Manually', 'OnRebuildingAll', 'AsNeeded' + ); var // All TPkgDependency are added to this AVL tree (sorted for names, not version!) @@ -651,6 +667,7 @@ function GetUsageOptionsList(PackageList: TList): TList; function PkgFileTypeIdentToType(const s: string): TPkgFileType; function LazPackageTypeIdentToType(const s: string): TLazPackageType; function GetPkgFileTypeLocalizedName(FileType: TPkgFileType): string; +function NameToAutoUpdatePolicy(const s: string): TPackageUpdatePolicy; procedure SortDependencyList(Dependencies: TList); procedure LoadPkgDependencyList(XMLConfig: TXMLConfig; const ThePath: string; @@ -677,7 +694,6 @@ function GetDependencyOwnerAsString(Dependency: TPkgDependency): string; function PackageFileNameIsValid(const AFilename: string): boolean; - implementation @@ -709,6 +725,13 @@ begin end; end; +function NameToAutoUpdatePolicy(const s: string): TPackageUpdatePolicy; +begin + for Result:=Low(TPackageUpdatePolicy) to High(TPackageUpdatePolicy) do + if AnsiCompareText(AutoUpdateNames[Result],s)=0 then exit; + Result:=pupAsNeeded; +end; + procedure LoadPkgDependencyList(XMLConfig: TXMLConfig; const ThePath: string; var First: TPkgDependency; ListType: TPkgDependencyList; Owner: TObject; HoldPackages: boolean); @@ -1559,11 +1582,6 @@ begin Result:=lpfAutoIncrementVersionOnBuild in FFlags; end; -function TLazPackage.GetAutoUpdate: boolean; -begin - Result:=lpfAutoUpdate in FFlags; -end; - function TLazPackage.GetComponentCount: integer; begin Result:=FComponents.Count; @@ -1629,13 +1647,10 @@ begin FAutoInstall:=AValue; end; -procedure TLazPackage.SetAutoUpdate(const AValue: boolean); +procedure TLazPackage.SetAutoUpdate(const AValue: TPackageUpdatePolicy); begin if AValue=AutoUpdate then exit; - if AValue then - Include(FFlags,lpfAutoUpdate) - else - Exclude(FFlags,lpfAutoUpdate); + FAutoUpdate:=AValue; Modified:=true; end; @@ -1670,7 +1685,7 @@ begin if FFlags=AValue then exit; ChangedFlags:=FFlags+AValue-(FFlags*AValue); FFlags:=AValue; - if ChangedFlags*[lpfAutoIncrementVersionOnBuild,lpfAutoUpdate]<>[] then + if ChangedFlags*[lpfAutoIncrementVersionOnBuild]<>[] then Modified:=true; end; @@ -1829,7 +1844,8 @@ begin UpdateSourceDirectories; // set some nice start values if not (lpfDestroying in FFlags) then begin - FFlags:=[lpfAutoIncrementVersionOnBuild,lpfAutoUpdate]; + FFlags:=[lpfAutoIncrementVersionOnBuild]; + FAutoUpdate:=pupAsNeeded; fCompilerOptions.UnitOutputDirectory:='lib'+PathDelim; FUsageOptions.UnitPath:='$(PkgOutDir)'; end else begin @@ -1899,10 +1915,6 @@ var Include(FFlags,lpfAutoIncrementVersionOnBuild) else Exclude(FFlags,lpfAutoIncrementVersionOnBuild); - if XMLConfig.GetValue(ThePath+'AutoUpdate/Value',true) then - Include(FFlags,lpfAutoUpdate) - else - Exclude(FFlags,lpfAutoUpdate); end; begin @@ -1916,6 +1928,8 @@ begin LockModified; Name:=XMLConfig.GetValue(Path+'Name/Value',''); FAuthor:=XMLConfig.GetValue(Path+'Author/Value',''); + FAutoUpdate:=NameToAutoUpdatePolicy( + XMLConfig.GetValue(Path+'AutoUpdate/Value','')); FCompilerOptions.LoadFromXMLConfig(XMLConfig,Path+'CompilerOptions/'); FDescription:=XMLConfig.GetValue(Path+'Description/Value',''); FLicense:=XMLConfig.GetValue(Path+'License/Value',''); @@ -1955,12 +1969,13 @@ procedure TLazPackage.SaveToXMLConfig(XMLConfig: TXMLConfig; const Path: string begin XMLConfig.SetDeleteValue(ThePath+'AutoIncrementVersionOnBuild/Value', AutoIncrementVersionOnBuild,true); - XMLConfig.SetDeleteValue(ThePath+'AutoUpdate/Value',AutoUpdate,true); end; begin XMLConfig.SetDeleteValue(Path+'Name/Value',FName,''); XMLConfig.SetDeleteValue(Path+'Author/Value',FAuthor,''); + XMLConfig.SetDeleteValue(Path+'AutoUpdate/Value',AutoUpdateNames[FAutoUpdate], + AutoUpdateNames[pupAsNeeded]); FCompilerOptions.SaveToXMLConfig(XMLConfig,Path+'CompilerOptions/'); XMLConfig.SetDeleteValue(Path+'Description/Value',FDescription,''); XMLConfig.SetDeleteValue(Path+'License/Value',FLicense,''); diff --git a/packager/packageeditor.pas b/packager/packageeditor.pas index ee45f943e9..72af339142 100644 --- a/packager/packageeditor.pas +++ b/packager/packageeditor.pas @@ -53,9 +53,11 @@ type SaveAs: boolean): TModalResult of object; TOnCompilePackage = function(Sender: TObject; APackage: TLazPackage; - CompileAll: boolean): TModalResult of object; + CompileClean, CompileRequired: boolean): TModalResult of object; TOnInstallPackage = function(Sender: TObject; APackage: TLazPackage): TModalResult of object; + TOnUninstallPackage = + function(Sender: TObject; APackage: TLazPackage): TModalResult of object; TOnCreateNewPkgFile = function(Sender: TObject; const Params: TAddToPkgResult): TModalResult of object; @@ -109,7 +111,8 @@ type procedure ApplyDependencyButtonClick(Sender: TObject); procedure CallRegisterProcCheckBoxClick(Sender: TObject); procedure ChangeFileTypeMenuItemClick(Sender: TObject); - procedure CompileAllClick(Sender: TObject); + procedure CompileAllCleanClick(Sender: TObject); + procedure CompileCleanClick(Sender: TObject); procedure CompileBitBtnClick(Sender: TObject); procedure CompilerOptionsBitBtnClick(Sender: TObject); procedure FilePropsGroupBoxResize(Sender: TObject); @@ -132,6 +135,7 @@ type procedure RemoveBitBtnClick(Sender: TObject); procedure SaveBitBtnClick(Sender: TObject); procedure SaveAsClick(Sender: TObject); + procedure UninstallClick(Sender: TObject); procedure UseMaxVersionCheckBoxClick(Sender: TObject); procedure UseMinVersionCheckBoxClick(Sender: TObject); private @@ -159,7 +163,7 @@ type constructor Create(TheOwner: TComponent); override; destructor Destroy; override; procedure DoSave(SaveAs: boolean); - procedure DoCompile(CompileAll: boolean); + procedure DoCompile(CompileClean, CompileRequired: boolean); public property LazPackage: TLazPackage read FLazPackage write SetLazPackage; end; @@ -180,6 +184,7 @@ type FOnOpenFile: TOnOpenFile; FOnOpenPackage: TOnOpenPackage; FOnSavePackage: TOnSavePackage; + FOnUninstallPackage: TOnUninstallPackage; function GetEditors(Index: integer): TPackageEditorForm; procedure ApplyLayout(AnEditor: TPackageEditorForm); procedure SaveLayout(AnEditor: TPackageEditorForm); @@ -203,9 +208,10 @@ type const Params: TAddToPkgResult): TModalResult; function SavePackage(APackage: TLazPackage; SaveAs: boolean): TModalResult; function CompilePackage(APackage: TLazPackage; - CompileAll: boolean): TModalResult; + CompileClean,CompileRequired: boolean): TModalResult; procedure UpdateAllEditors; function InstallPackage(APackage: TLazPackage): TModalResult; + function UninstallPackage(APackage: TLazPackage): TModalResult; public property Editors[Index: integer]: TPackageEditorForm read GetEditors; property OnCreateNewFile: TOnCreateNewPkgFile read FOnCreateNewFile @@ -222,6 +228,8 @@ type write FOnCompilePackage; property OnInstallPackage: TOnInstallPackage read FOnInstallPackage write FOnInstallPackage; + property OnUninstallPackage: TOnUninstallPackage read FOnUninstallPackage + write FOnUninstallPackage; end; var @@ -428,11 +436,18 @@ begin AddPopupMenuItem('Save',@SaveBitBtnClick,SaveBitBtn.Enabled); AddPopupMenuItem('Save As',@SaveAsClick,not LazPackage.AutoCreated); + AddPopupMenuItem('-',nil,true); AddPopupMenuItem('Compile',@CompileBitBtnClick,CompileBitBtn.Enabled); - AddPopupMenuItem('Compile All',@CompileAllClick,CompileBitBtn.Enabled); + AddPopupMenuItem('Recompile clean',@CompileCleanClick,CompileBitBtn.Enabled); + AddPopupMenuItem('Recompile all required',@CompileAllCleanClick,CompileBitBtn.Enabled); + AddPopupMenuItem('-',nil,true); AddPopupMenuItem('Add',@AddBitBtnClick,AddBitBtn.Enabled); AddPopupMenuItem('Remove',@RemoveBitBtnClick,RemoveBitBtn.Enabled); + AddPopupMenuItem('-',nil,true); AddPopupMenuItem('Install',@InstallBitBtnClick,InstallBitBtn.Enabled); + AddPopupMenuItem('Uninstall',@UninstallClick, + (LazPackage.Installed<>pitNope) or (LazPackage.AutoInstall<>pitNope)); + AddPopupMenuItem('-',nil,true); AddPopupMenuItem('General Options',@OptionsBitBtnClick,OptionsBitBtn.Enabled); AddPopupMenuItem('Compiler Options',@CompilerOptionsBitBtnClick,CompilerOptionsBitBtn.Enabled); @@ -653,6 +668,11 @@ begin DoSave(true); end; +procedure TPackageEditorForm.UninstallClick(Sender: TObject); +begin + PackageEditors.UninstallPackage(LazPackage); +end; + procedure TPackageEditorForm.UseMaxVersionCheckBoxClick(Sender: TObject); begin MaxVersionEdit.Enabled:=UseMaxVersionCheckBox.Checked; @@ -876,14 +896,19 @@ begin end; end; -procedure TPackageEditorForm.CompileAllClick(Sender: TObject); +procedure TPackageEditorForm.CompileAllCleanClick(Sender: TObject); begin - DoCompile(true); + DoCompile(true,true); +end; + +procedure TPackageEditorForm.CompileCleanClick(Sender: TObject); +begin + DoCompile(true,false); end; procedure TPackageEditorForm.CompileBitBtnClick(Sender: TObject); begin - DoCompile(false); + DoCompile(false,false); end; procedure TPackageEditorForm.CompilerOptionsBitBtnClick(Sender: TObject); @@ -1535,9 +1560,9 @@ begin UpdateStatusBar; end; -procedure TPackageEditorForm.DoCompile(CompileAll: boolean); +procedure TPackageEditorForm.DoCompile(CompileClean, CompileRequired: boolean); begin - PackageEditors.CompilePackage(LazPackage,CompileAll); + PackageEditors.CompilePackage(LazPackage,CompileClean,CompileRequired); UpdateButtons; UpdateTitle; UpdateStatusBar; @@ -1799,10 +1824,10 @@ begin end; function TPackageEditors.CompilePackage(APackage: TLazPackage; - CompileAll: boolean): TModalResult; + CompileClean, CompileRequired: boolean): TModalResult; begin if Assigned(OnCompilePackage) then - Result:=OnCompilePackage(Self,APackage,CompileAll); + Result:=OnCompilePackage(Self,APackage,CompileClean,CompileRequired); end; procedure TPackageEditors.UpdateAllEditors; @@ -1814,7 +1839,14 @@ end; function TPackageEditors.InstallPackage(APackage: TLazPackage): TModalResult; begin - if Assigned(OnInstallPackage) then Result:=OnInstallPackage(Self,APackage); + if Assigned(OnInstallPackage) then + Result:=OnInstallPackage(Self,APackage); +end; + +function TPackageEditors.UninstallPackage(APackage: TLazPackage): TModalResult; +begin + if Assigned(OnUninstallPackage) then + Result:=OnUninstallPackage(Self,APackage); end; { TPackageEditorLayout } diff --git a/packager/packagesystem.pas b/packager/packagesystem.pas index 2d8e886221..0f458aec95 100644 --- a/packager/packagesystem.pas +++ b/packager/packagesystem.pas @@ -129,6 +129,7 @@ type FirstDependency: TPkgDependency): TList; function FindUnsavedDependencyPath(APackage: TLazPackage; FirstDependency: TPkgDependency): TList; + function FindAutoInstallDependencyPath(ChildPackage: TLazPackage): TList; function FindFileInAllPackages(const TheFilename: string; ResolveLinks, IgnoreDeleted: boolean): TPkgFile; function FindLowestPkgNodeByName(const PkgName: string): TAVLTreeNode; @@ -145,7 +146,8 @@ type function FindUnitInAllPackages(const TheUnitName: string; IgnoreDeleted: boolean): TPkgFile; function GetAutoCompilationOrder(APackage: TLazPackage; - FirstDependency: TPkgDependency): TList; + FirstDependency: TPkgDependency; + Policies: TPackageUpdatePolicies): TList; function GetBrokenDependenciesWhenChangingPkgID(APackage: TLazPackage; const NewName: string; NewVersion: TPkgVersion): TList; function PackageCanBeReplaced(OldPackage, NewPackage: TLazPackage): boolean; @@ -803,7 +805,7 @@ begin Author:='FPC team'; License:='LGPL-2'; AutoInstall:=pitStatic; - AutoUpdate:=false; + AutoUpdate:=pupManually; Description:='The FCL - FreePascal Component Library ' +'provides the base classes for object pascal.'; PackageType:=lptDesignTime; @@ -838,7 +840,7 @@ begin Author:='Lazarus'; License:='LGPL-2'; AutoInstall:=pitStatic; - AutoUpdate:=false; + AutoUpdate:=pupManually; Description:='The LCL - Lazarus Component Library ' +'contains all base components for form editing.'; PackageType:=lptDesignTime; @@ -890,7 +892,7 @@ begin Author:='SynEdit - http://sourceforge.net/projects/synedit/'; License:='LGPL-2'; AutoInstall:=pitStatic; - AutoUpdate:=false; + AutoUpdate:=pupManually; Description:='SynEdit - the editor component used by Lazarus. ' +'http://sourceforge.net/projects/synedit/'; PackageType:=lptDesignTime; @@ -937,7 +939,7 @@ begin Version.SetValues(1,0,1,1); Author:='Anonymous'; AutoInstall:=pitStatic; - AutoUpdate:=false; + AutoUpdate:=pupManually; Description:='This is the default package. ' +'Used only for components without a package. ' +'These components are outdated.'; @@ -1214,10 +1216,53 @@ begin Result.Insert(0,APackage); end; -function TLazPackageGraph.GetAutoCompilationOrder(APackage: TLazPackage; - FirstDependency: TPkgDependency): TList; +function TLazPackageGraph.FindAutoInstallDependencyPath( + ChildPackage: TLazPackage): TList; - procedure GetTopologicalOrder(Dependency: TPkgDependency); + procedure FindAutoInstallParent(APackage: TLazPackage); + var + ParentPackage: TLazPackage; + Dependency: TPkgDependency; + begin + Dependency:=APackage.FirstUsedByDependency; + while Dependency<>nil do begin + if Dependency.Owner is TLazPackage then begin + ParentPackage:=TLazPackage(Dependency.Owner); + if not (lpfVisited in ParentPackage.Flags) then begin + ParentPackage.Flags:=ParentPackage.Flags+[lpfVisited]; + if ParentPackage.AutoInstall<>pitNope then begin + // auto install parent found + if Result=nil then Result:=TList.Create; + Result.Add(ParentPackage); + Result.Add(APackage); + exit; + end; + FindAutoInstallParent(ParentPackage); + if Result<>nil then begin + // build path + Result.Add(APackage); + exit; + end; + end; + end; + Dependency:=Dependency.NextRequiresDependency; + end; + end; + +begin + Result:=nil; + MarkAllPackagesAsNotVisited; + ChildPackage.Flags:=ChildPackage.Flags+[lpfVisited]; + FindAutoInstallParent(ChildPackage); +end; + +function TLazPackageGraph.GetAutoCompilationOrder(APackage: TLazPackage; + FirstDependency: TPkgDependency; Policies: TPackageUpdatePolicies): TList; +// Returns all required auto update packages, including indirect requirements. +// The packages will be in topological order, with the package that should be +// compiled first at the end. + + procedure GetLevelOrder(Dependency: TPkgDependency); var RequiredPackage: TLazPackage; begin @@ -1226,9 +1271,9 @@ function TLazPackageGraph.GetAutoCompilationOrder(APackage: TLazPackage; RequiredPackage:=Dependency.RequiredPackage; if not (lpfVisited in RequiredPackage.Flags) then begin RequiredPackage.Flags:=RequiredPackage.Flags+[lpfVisited]; - if RequiredPackage.AutoUpdate then begin + if RequiredPackage.AutoUpdate in Policies then begin // add first all needed packages - GetTopologicalOrder(RequiredPackage.FirstRequiredDependency); + GetLevelOrder(RequiredPackage.FirstRequiredDependency); // then add this package if Result=nil then Result:=TList.Create; Result.Add(RequiredPackage); @@ -1246,7 +1291,7 @@ begin APackage.Flags:=APackage.Flags+[lpfVisited]; FirstDependency:=APackage.FirstRequiredDependency; end; - GetTopologicalOrder(FirstDependency); + GetLevelOrder(FirstDependency); end; procedure TLazPackageGraph.MarkAllPackagesAsNotVisited; @@ -1368,7 +1413,7 @@ var Dependency: TPkgDependency; begin Result:=false; - if OldPackage.Broken and (AnsiCompareText(OldPackage.Name,NewPackage.Name)=0) + if OldPackage.Missing and (AnsiCompareText(OldPackage.Name,NewPackage.Name)=0) then begin Result:=true; exit; @@ -1557,14 +1602,14 @@ begin BrokenPackage:=TLazPackage.Create; with BrokenPackage do begin BeginUpdate; - Broken:=true; + Missing:=true; AutoCreated:=true; Name:=Dependency.PackageName; Filename:=''; Version.SetValues(0,0,0,0); Author:='?'; License:='?'; - AutoUpdate:=false; + AutoUpdate:=pupManually; Description:='This package is installed, but the lpk file was not found.' +'All its components are deactivated. Please fix this.'; PackageType:=lptDesignTime; diff --git a/packager/pkgmanager.pas b/packager/pkgmanager.pas index 9e9326b05c..371df62fdf 100644 --- a/packager/pkgmanager.pas +++ b/packager/pkgmanager.pas @@ -59,11 +59,14 @@ type TPkgManager = class(TBasePkgManager) // events function OnPackageEditorCompilePackage(Sender: TObject; - APackage: TLazPackage; CompileAll: boolean): TModalResult; + APackage: TLazPackage; + CompileClean, CompileRequired: boolean): TModalResult; function OnPackageEditorCreateFile(Sender: TObject; const Params: TAddToPkgResult): TModalResult; function OnPackageEditorInstallPackage(Sender: TObject; - APackage: TLazPackage): TModalResult; + APackage: TLazPackage): TModalResult; + function OnPackageEditorUninstallPackage(Sender: TObject; + APackage: TLazPackage): TModalResult; function OnPackageEditorOpenPackage(Sender: TObject; APackage: TLazPackage ): TModalResult; function OnPackageEditorSavePackage(Sender: TObject; APackage: TLazPackage; @@ -98,7 +101,8 @@ type // helper functions function DoShowSavePackageAsDialog(APackage: TLazPackage): TModalResult; function CompileRequiredPackages(APackage: TLazPackage; - FirstDependency: TPkgDependency): TModalResult; + FirstDependency: TPkgDependency; + Policies: TPackageUpdatePolicies): TModalResult; function CheckPackageGraphForCompilation(APackage: TLazPackage; FirstDependency: TPkgDependency): TModalResult; function DoPreparePackageOutputDirectory(APackage: TLazPackage): TModalResult; @@ -168,6 +172,7 @@ type NewFilename: string): TModalResult; override; function DoAddActiveUnitToAPackage: TModalResult; function DoInstallPackage(APackage: TLazPackage): TModalResult; + function DoUninstallPackage(APackage: TLazPackage): TModalResult; function DoCompileAutoInstallPackages(Flags: TPkgCompileFlags ): TModalResult; override; function DoSaveAutoInstallConfig: TModalResult; override; @@ -253,12 +258,13 @@ begin end; function TPkgManager.OnPackageEditorCompilePackage(Sender: TObject; - APackage: TLazPackage; CompileAll: boolean): TModalResult; + APackage: TLazPackage; CompileClean, CompileRequired: boolean): TModalResult; var Flags: TPkgCompileFlags; begin Flags:=[]; - if CompileAll then Include(Flags,pcfCleanCompile); + if CompileClean then Include(Flags,pcfCleanCompile); + if CompileRequired then Include(Flags,pcfCompileDependenciesClean); Result:=DoCompilePackage(APackage,Flags); end; @@ -318,6 +324,12 @@ begin Result:=DoInstallPackage(APackage); end; +function TPkgManager.OnPackageEditorUninstallPackage(Sender: TObject; + APackage: TLazPackage): TModalResult; +begin + Result:=DoUninstallPackage(APackage); +end; + procedure TPkgManager.OnPackageEditorFreeEditor(APackage: TLazPackage); begin APackage.Editor:=nil; @@ -622,13 +634,15 @@ begin end; function TPkgManager.CompileRequiredPackages(APackage: TLazPackage; - FirstDependency: TPkgDependency): TModalResult; + FirstDependency: TPkgDependency; + Policies: TPackageUpdatePolicies): TModalResult; var AutoPackages: TList; i: Integer; begin writeln('TPkgManager.CompileRequiredPackages A '); - AutoPackages:=PackageGraph.GetAutoCompilationOrder(APackage,FirstDependency); + AutoPackages:=PackageGraph.GetAutoCompilationOrder(APackage,FirstDependency, + Policies); if AutoPackages<>nil then begin writeln('TPkgManager.CompileRequiredPackages B Count=',AutoPackages.Count); try @@ -1166,15 +1180,17 @@ constructor TPkgManager.Create(TheOwner: TComponent); begin inherited Create(TheOwner); OnGetDependencyOwnerDescription:=@GetDependencyOwnerDescription; - - + + // componentpalette IDEComponentPalette:=TComponentPalette.Create; IDEComponentPalette.OnEndUpdate:=@IDEComponentPaletteEndUpdate; TComponentPalette(IDEComponentPalette).OnOpenPackage:=@IDEComponentPaletteOpenPackage; - + + // package links PkgLinks:=TPackageLinks.Create; PkgLinks.UpdateAll; + // package graph PackageGraph:=TLazPackageGraph.Create; PackageGraph.OnChangePackageName:=@PackageGraphChangePackageName; PackageGraph.OnAddPackage:=@PackageGraphAddPackage; @@ -1183,6 +1199,7 @@ begin PackageGraph.OnBeginUpdate:=@PackageGraphBeginUpdate; PackageGraph.OnEndUpdate:=@PackageGraphEndUpdate; + // package editors PackageEditors:=TPackageEditors.Create; PackageEditors.OnOpenFile:=@MainIDE.DoOpenMacroFile; PackageEditors.OnOpenPackage:=@OnPackageEditorOpenPackage; @@ -1193,7 +1210,9 @@ begin PackageEditors.OnSavePackage:=@OnPackageEditorSavePackage; PackageEditors.OnCompilePackage:=@OnPackageEditorCompilePackage; PackageEditors.OnInstallPackage:=@OnPackageEditorInstallPackage; - + PackageEditors.OnUninstallPackage:=@OnPackageEditorUninstallPackage; + + // package macros CodeToolBoss.DefineTree.MacroFunctions.AddExtended( 'PKGSRCPATH',nil,@MacroFunctionPkgSrcPath); CodeToolBoss.DefineTree.MacroFunctions.AddExtended( @@ -1201,6 +1220,7 @@ begin CodeToolBoss.DefineTree.MacroFunctions.AddExtended( 'PKGINCPATH',nil,@MacroFunctionPkgIncPath); + // idle handler Application.AddOnIdleHandler(@OnApplicationIdle); end; @@ -1685,7 +1705,8 @@ begin try // automatically compile required packages if not (pcfDoNotCompileDependencies in Flags) then begin - Result:=CompileRequiredPackages(nil,AProject.FirstRequiredDependency); + Result:=CompileRequiredPackages(nil,AProject.FirstRequiredDependency, + [pupAsNeeded]); if Result<>mrOk then exit; end; finally @@ -1703,6 +1724,7 @@ var CompilerParams: String; EffektiveCompilerParams: String; SrcFilename: String; + CompilePolicies: TPackageUpdatePolicies; begin Result:=mrCancel; @@ -1726,7 +1748,10 @@ begin try // automatically compile required packages if not (pcfDoNotCompileDependencies in Flags) then begin - Result:=CompileRequiredPackages(APackage,nil); + CompilePolicies:=[pupAsNeeded]; + if pcfCompileDependenciesClean in Flags then + Include(CompilePolicies,pupOnRebuildingAll); + Result:=CompileRequiredPackages(APackage,nil,[pupAsNeeded]); if Result<>mrOk then exit; end; @@ -2047,6 +2072,7 @@ begin 'The package "'+APackage.IDAsString+'" was marked for installation.'#13 +'Currently lazarus only supports static linked packages. The real ' +'installation needs rebuilding of lazarus.'#13 + +#13 +'Should lazarus now be rebuilt?', mtConfirmation,[mbYes,mbNo],0); if Result=mrNo then begin @@ -2064,6 +2090,70 @@ begin Result:=mrOk; end; +function TPkgManager.DoUninstallPackage(APackage: TLazPackage): TModalResult; +var + DependencyPath: TList; + ParentPackage: TLazPackage; + Dependency: TPkgDependency; +begin + if (APackage.Installed=pitNope) and (APackage.AutoInstall=pitNope) then exit; + + // check if package is required by auto install package + DependencyPath:=PackageGraph.FindAutoInstallDependencyPath(APackage); + if DependencyPath<>nil then begin + DoShowPackageGraphPathList(DependencyPath); + ParentPackage:=TLazPackage(DependencyPath[0]); + Result:=MessageDlg('Package is required', + 'The package '+APackage.IDAsString+' is required by ' + +ParentPackage.IDAsString+', which is marked for installation.'#13 + +'See package graph.', + mtError,[mbCancel,mbAbort],0); + exit; + end; + + PackageGraph.BeginUpdate(false); + try + // save package + if APackage.IsVirtual or APackage.Modified then begin + Result:=DoSavePackage(APackage,[]); + if Result<>mrOk then exit; + end; + + // remove package from auto installed packages + if APackage.AutoInstall<>pitNope then begin + APackage.AutoInstall:=pitNope; + Dependency:=FindCompatibleDependencyInList(FirstAutoInstallDependency, + pdlRequires,APackage); + if Dependency<>nil then begin + Dependency.RemoveFromList(FirstAutoInstallDependency,pdlRequires); + Dependency.Free; + end; + SaveAutoInstallDependencies; + end; + + // ask user to rebuilt Lazarus now + Result:=MessageDlg('Rebuild Lazarus?', + 'The package "'+APackage.IDAsString+'" was marked.'#13 + +'Currently lazarus only supports static linked packages. The real ' + +'un-installation needs rebuilding of lazarus.'#13 + +#13 + +'Should lazarus now be rebuilt?', + mtConfirmation,[mbYes,mbNo],0); + if Result=mrNo then begin + Result:=mrOk; + exit; + end; + + // rebuild Lazarus + Result:=MainIDE.DoBuildLazarus([blfWithStaticPackages]); + if Result<>mrOk then exit; + + finally + PackageGraph.EndUpdate; + end; + Result:=mrOk; +end; + function TPkgManager.DoCompileAutoInstallPackages( Flags: TPkgCompileFlags): TModalResult; var @@ -2100,7 +2190,7 @@ begin end; // compile all auto install dependencies - Result:=CompileRequiredPackages(nil,FirstAutoInstallDependency); + Result:=CompileRequiredPackages(nil,FirstAutoInstallDependency,[pupAsNeeded]); if Result<>mrOk then exit; finally diff --git a/packager/pkgoptionsdlg.pas b/packager/pkgoptionsdlg.pas index 72fca92d99..a069a404c6 100644 --- a/packager/pkgoptionsdlg.pas +++ b/packager/pkgoptionsdlg.pas @@ -303,13 +303,13 @@ begin x:=3; y:=3; w:=(IDEPage.ClientWidth-2*x); - h:=85; + h:=90; with PkgTypeRadioGroup do begin SetBounds(x,y,w,h); - inc(y,h+5); + inc(y,h+10); end; - h:=75; + h:=90; with UpdateRadioGroup do SetBounds(x,y,w,h); end; @@ -381,7 +381,11 @@ begin // Usage page LazPackage.PackageType:=NewPackageType; - LazPackage.AutoUpdate:=(UpdateRadioGroup.ItemIndex=0); + case UpdateRadioGroup.ItemIndex of + 2: LazPackage.AutoUpdate:=pupManually; + 1: LazPackage.AutoUpdate:=pupOnRebuildingAll; + else LazPackage.AutoUpdate:=pupAsNeeded; + end; with LazPackage.UsageOptions do begin UnitPath:=UnitPathEdit.Text; IncludePath:=IncludePathEdit.Text; @@ -664,8 +668,9 @@ begin Caption:='Update/Rebuild'; with Items do begin BeginUpdate; - Add('Automatically re-compile as needed'); - Add('Manual compilation'); + Add('Automatically rebuild as needed'); + Add('Auto rebuild when rebuilding all'); + Add('Manual compilation (never automatically)'); EndUpdate; end; ItemIndex:=0; @@ -835,10 +840,11 @@ begin // Usage page ReadPkgTypeFromPackage; - if LazPackage.AutoUpdate then - UpdateRadioGroup.ItemIndex:=0 - else - UpdateRadioGroup.ItemIndex:=1; + case LazPackage.AutoUpdate of + pupAsNeeded: UpdateRadioGroup.ItemIndex:=0; + pupOnRebuildingAll: UpdateRadioGroup.ItemIndex:=1; + else UpdateRadioGroup.ItemIndex:=2; + end; with LazPackage.UsageOptions do begin UnitPathEdit.Text:=UnitPath;