diff --git a/.gitattributes b/.gitattributes
index 97f087be0a..eae411d908 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -6729,6 +6729,8 @@ packager/addtopackagedlg.lfm svneol=native#text/plain
packager/addtopackagedlg.pas svneol=native#text/pascal
packager/basepkgmanager.pas svneol=native#text/pascal
packager/brokendependenciesdlg.pas svneol=native#text/pascal
+packager/cleanpkgdeps.lfm svneol=native#text/plain
+packager/cleanpkgdeps.pas svneol=native#text/plain
packager/confirmpkglistdlg.lfm svneol=native#text/plain
packager/confirmpkglistdlg.pas svneol=native#text/plain
packager/frames/package_description_options.lfm svneol=native#text/plain
diff --git a/ide/lazarus.lpi b/ide/lazarus.lpi
index ef517b0a1b..fda6846d11 100644
--- a/ide/lazarus.lpi
+++ b/ide/lazarus.lpi
@@ -63,7 +63,7 @@
-
+
@@ -737,6 +737,13 @@
+
+
+
+
+
+
+
@@ -746,7 +753,7 @@
-
+
diff --git a/ide/lazarusidestrconsts.pas b/ide/lazarusidestrconsts.pas
index b6d955661a..700c17ec8f 100644
--- a/ide/lazarusidestrconsts.pas
+++ b/ide/lazarusidestrconsts.pas
@@ -5658,6 +5658,7 @@ resourcestring
lisRunTimeOnlyPackagesAreOnlyForProjectsTheyCanNotBeI = '"Run time only" '
+'packages are only for projects. They can not be installed in the IDE, '
+'not even indirectly.';
+ lisPckEditCleanUpDependencies = 'Clean up dependencies ...';
implementation
diff --git a/packager/cleanpkgdeps.lfm b/packager/cleanpkgdeps.lfm
new file mode 100644
index 0000000000..9bfd78b0e6
--- /dev/null
+++ b/packager/cleanpkgdeps.lfm
@@ -0,0 +1,58 @@
+object CleanPkgDepsDlg: TCleanPkgDepsDlg
+ Left = 270
+ Height = 380
+ Top = 176
+ Width = 522
+ Caption = 'CleanPkgDepsDlg'
+ ClientHeight = 380
+ ClientWidth = 522
+ OnCreate = FormCreate
+ Position = poScreenCenter
+ LCLVersion = '1.1'
+ object ButtonPanel1: TButtonPanel
+ Left = 6
+ Height = 30
+ Top = 344
+ Width = 510
+ OKButton.Name = 'OKButton'
+ OKButton.DefaultCaption = True
+ HelpButton.Name = 'HelpButton'
+ HelpButton.DefaultCaption = True
+ CloseButton.Name = 'CloseButton'
+ CloseButton.DefaultCaption = True
+ CancelButton.Name = 'CancelButton'
+ CancelButton.DefaultCaption = True
+ TabOrder = 0
+ ShowButtons = [pbOK, pbCancel]
+ end
+ object TransitivityGroupBox: TGroupBox
+ Left = 0
+ Height = 338
+ Top = 0
+ Width = 522
+ Align = alClient
+ Caption = 'TransitivityGroupBox'
+ ClientHeight = 316
+ ClientWidth = 514
+ TabOrder = 1
+ object TransitivityTreeView: TTreeView
+ Left = 0
+ Height = 300
+ Top = 16
+ Width = 514
+ Align = alClient
+ DefaultItemHeight = 18
+ TabOrder = 0
+ end
+ object TransitivityLabel: TLabel
+ Left = 0
+ Height = 16
+ Top = 0
+ Width = 514
+ Align = alTop
+ Caption = 'TransitivityLabel'
+ ParentColor = False
+ WordWrap = True
+ end
+ end
+end
diff --git a/packager/cleanpkgdeps.pas b/packager/cleanpkgdeps.pas
new file mode 100644
index 0000000000..40b59729cb
--- /dev/null
+++ b/packager/cleanpkgdeps.pas
@@ -0,0 +1,151 @@
+unit CleanPkgDeps;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes, SysUtils, FileUtil, LvlGraphCtrl, Forms, Controls, Graphics, Dialogs,
+ ButtonPanel, ComCtrls, ExtCtrls, StdCtrls, LazarusIDEStrConsts, Project,
+ PackageDefs;
+
+type
+
+ { TCleanPkgDepsDlg }
+
+ TCleanPkgDepsDlg = class(TForm)
+ ButtonPanel1: TButtonPanel;
+ TransitivityGroupBox: TGroupBox;
+ TransitivityLabel: TLabel;
+ TransitivityTreeView: TTreeView;
+ procedure FormCreate(Sender: TObject);
+ private
+ FOwners: TFPList;
+ procedure SetOwners(AValue: TFPList);
+ procedure UpdateTransitivityTree;
+ procedure UpdateButtons;
+ function IsTVNodeChecked(TVNode: TTreeNode): boolean;
+ procedure AddTransitivities(NodeCaption: string;
+ FirstDependency: TPkgDependency);
+ public
+ property Owners: TFPList read FOwners write SetOwners;
+ end;
+
+var
+ CleanPkgDepsDlg: TCleanPkgDepsDlg;
+
+function ShowCleanPkgDepDlg(Pkg: TLazPackage): TModalResult;
+function ShowCleanPkgDepDlg(AProject: TProject): TModalResult;
+function ShowCleanPkgDepDlg(Owners: TFPList; FreeList: boolean): TModalResult;
+
+implementation
+
+function ShowCleanPkgDepDlg(Pkg: TLazPackage): TModalResult;
+var
+ Owners: TFPList;
+begin
+ Owners:=TFPList.Create;
+ Owners.Add(Pkg);
+ Result:=ShowCleanPkgDepDlg(Owners,true);
+end;
+
+function ShowCleanPkgDepDlg(AProject: TProject): TModalResult;
+var
+ Owners: TFPList;
+begin
+ Owners:=TFPList.Create;
+ Owners.Add(AProject);
+ Result:=ShowCleanPkgDepDlg(Owners,true);
+end;
+
+function ShowCleanPkgDepDlg(Owners: TFPList; FreeList: boolean): TModalResult;
+var
+ Dlg: TCleanPkgDepsDlg;
+begin
+ Dlg:=TCleanPkgDepsDlg.Create(nil);
+ try
+ Dlg.Owners:=Owners;
+ Result:=Dlg.ShowModal;
+ finally
+ if FreeList then
+ Owners.Free;
+ Dlg.Free;
+ end;
+end;
+
+{$R *.lfm}
+
+{ TCleanPkgDepsDlg }
+
+procedure TCleanPkgDepsDlg.FormCreate(Sender: TObject);
+begin
+ Caption:='Clean up package dependencies';
+ TransitivityGroupBox.Caption:='Transitivity';
+ TransitivityLabel.Caption:='The following dependencies are not needed, because of the automatic transitivity between package dependencies.';
+ ButtonPanel1.OKButton.Caption:='Delete dependencies';
+end;
+
+procedure TCleanPkgDepsDlg.SetOwners(AValue: TFPList);
+begin
+ if FOwners=AValue then Exit;
+ FOwners:=AValue;
+ UpdateTransitivityTree;
+ UpdateButtons;
+end;
+
+procedure TCleanPkgDepsDlg.UpdateTransitivityTree;
+var
+ i: Integer;
+ CurOwner: TObject;
+ AProject: TProject;
+ APackage: TLazPackage;
+begin
+ TransitivityTreeView.BeginUpdate;
+ TransitivityTreeView.Items.Clear;
+ for i:=0 to Owners.Count-1 do begin
+ CurOwner:=TObject(Owners[i]);
+ if CurOwner is TProject then begin
+ AProject:=TProject(CurOwner);
+ AddTransitivities('-Project-',AProject.FirstRequiredDependency);
+ end else if CurOwner is TLazPackage then begin
+ APackage:=TLazPackage(CurOwner);
+ AddTransitivities(APackage.IDAsString,APackage.FirstRequiredDependency);
+ end;
+ end;
+ TransitivityTreeView.EndUpdate;
+end;
+
+procedure TCleanPkgDepsDlg.UpdateButtons;
+var
+ i: Integer;
+ TVNode: TTreeNode;
+ CheckCnt: Integer;
+begin
+ CheckCnt:=0;
+ for i:=0 to TransitivityTreeView.Items.Count-1 do begin
+ TVNode:=TransitivityTreeView.Items[i];
+ if IsTVNodeChecked(TVNode) then
+ CheckCnt+=1;
+ end;
+ ButtonPanel1.OKButton.Enabled:=CheckCnt>0;
+end;
+
+function TCleanPkgDepsDlg.IsTVNodeChecked(TVNode: TTreeNode): boolean;
+begin
+ Result:=(TVNode<>nil) and (TVNode.StateIndex=1);
+end;
+
+procedure TCleanPkgDepsDlg.AddTransitivities(NodeCaption: string;
+ FirstDependency: TPkgDependency);
+var
+ Dependency: TPkgDependency;
+begin
+ Dependency:=FirstDependency;
+ while Dependency<>nil do begin
+
+ Dependency:=Dependency.NextRequiresDependency;
+ end;
+end;
+
+end.
+
diff --git a/packager/packageeditor.pas b/packager/packageeditor.pas
index b9b2475855..1ad5bf1942 100644
--- a/packager/packageeditor.pas
+++ b/packager/packageeditor.pas
@@ -42,40 +42,47 @@ uses
MainIntf, IDEProcs, LazConf, LazarusIDEStrConsts, IDEOptionDefs, IDEDefs,
IDEContextHelpEdit, CompilerOptions, ComponentReg,
PackageDefs, AddToPackageDlg, PkgVirtualUnitEditor,
- MissingPkgFilesDlg, PackageSystem;
+ MissingPkgFilesDlg, PackageSystem, CleanPkgDeps;
const
PackageEditorMenuRootName = 'PackageEditor';
PackageEditorMenuFilesRootName = 'PackageEditorFiles';
PackageEditorWindowPrefix = 'PackageEditor_';
var
+ // single file
PkgEditMenuOpenFile: TIDEMenuCommand;
PkgEditMenuRemoveFile: TIDEMenuCommand;
PkgEditMenuReAddFile: TIDEMenuCommand;
PkgEditMenuEditVirtualUnit: TIDEMenuCommand;
PkgEditMenuSectionFileType: TIDEMenuSection;
+ // directories
PkgEditMenuExpandDirectory: TIDEMenuCommand;
PkgEditMenuCollapseDirectory: TIDEMenuCommand;
PkgEditMenuUseAllUnitsInDirectory: TIDEMenuCommand;
PkgEditMenuUseNoUnitsInDirectory: TIDEMenuCommand;
+ // dependencies
PkgEditMenuOpenPackage: TIDEMenuCommand;
PkgEditMenuRemoveDependency: TIDEMenuCommand;
PkgEditMenuReAddDependency: TIDEMenuCommand;
PkgEditMenuDependencyStoreFileNameAsDefault: TIDEMenuCommand;
PkgEditMenuDependencyStoreFileNameAsPreferred: TIDEMenuCommand;
PkgEditMenuDependencyClearStoredFileName: TIDEMenuCommand;
+ PkgEditMenuCleanDependencies: TIDEMenuCommand;
+ // multi files
PkgEditMenuSortFiles: TIDEMenuCommand;
PkgEditMenuFixFilesCase: TIDEMenuCommand;
PkgEditMenuShowMissingFiles: TIDEMenuCommand;
+ // package
PkgEditMenuSave: TIDEMenuCommand;
PkgEditMenuSaveAs: TIDEMenuCommand;
PkgEditMenuRevert: TIDEMenuCommand;
PkgEditMenuPublish: TIDEMenuCommand;
+ // compile
PkgEditMenuCompile: TIDEMenuCommand;
PkgEditMenuRecompileClean: TIDEMenuCommand;
PkgEditMenuRecompileAllRequired: TIDEMenuCommand;
@@ -172,6 +179,7 @@ type
procedure ApplyDependencyButtonClick(Sender: TObject);
procedure CallRegisterProcCheckBoxChange(Sender: TObject);
procedure ChangeFileTypeMenuItemClick(Sender: TObject);
+ procedure CleanDependenciesMenuItemClick(Sender: TObject);
procedure ClearDependencyFilenameMenuItemClick(Sender: TObject);
procedure CollapseDirectoryMenuItemClick(Sender: TObject);
procedure CompileAllCleanClick(Sender: TObject);
@@ -438,7 +446,7 @@ begin
PkgEditMenuUseAllUnitsInDirectory:=RegisterIDEMenuCommand(AParent, 'Use all units in directory', lisPEUseAllUnitsInDirectory);
PkgEditMenuUseNoUnitsInDirectory:=RegisterIDEMenuCommand(AParent, 'Use no units in directory', lisPEUseNoUnitsInDirectory);
- // register the section for operations on single dependencies
+ // register the section for operations on dependencies
PkgEditMenuSectionDependency:=RegisterIDEMenuSection(PackageEditorMenuFilesRoot,'Dependency');
AParent:=PkgEditMenuSectionDependency;
PkgEditMenuOpenPackage:=RegisterIDEMenuCommand(AParent,'Open Package',lisMenuOpenPackage);
@@ -447,6 +455,7 @@ begin
PkgEditMenuDependencyStoreFileNameAsDefault:=RegisterIDEMenuCommand(AParent,'Dependency Store Filename As Default',lisPckEditStoreFileNameAsDefaultForThisDependency);
PkgEditMenuDependencyStoreFileNameAsPreferred:=RegisterIDEMenuCommand(AParent,'Dependency Store Filename As Preferred',lisPckEditStoreFileNameAsPreferredForThisDependency);
PkgEditMenuDependencyClearStoredFileName:=RegisterIDEMenuCommand(AParent,'Dependency Clear Stored Filename',lisPckEditClearDefaultPreferredFilenameOfDependency);
+ PkgEditMenuCleanDependencies:=RegisterIDEMenuCommand(AParent, 'Clean up dependencies', lisPckEditCleanUpDependencies);
// register the section for operations on all files
PkgEditMenuSectionFiles:=RegisterIDEMenuSection(PackageEditorMenuRoot,'Files');
@@ -618,23 +627,31 @@ begin
end;
// items for dependencies, under section PkgEditMenuSectionDependency
- if CurDependency<>nil then begin
- PkgEditMenuSectionDependency.Visible:=true;
- SetItem(PkgEditMenuOpenPackage,@OpenFileMenuItemClick,CurDependency.RequiredPackage<>nil);
- SetItem(PkgEditMenuRemoveDependency,@RemoveBitBtnClick,not Removed,
- RemoveBitBtn.Enabled);
- SetItem(PkgEditMenuReAddDependency,@ReAddMenuItemClick,Removed and AddBitBtn.Enabled);
- SetItem(PkgEditMenuDependencyStoreFileNameAsDefault,
- @SetDependencyDefaultFilenameMenuItemClick,not Removed,
- Writable and (CurDependency.RequiredPackage<>nil));
- SetItem(PkgEditMenuDependencyStoreFileNameAsPreferred,
- @SetDependencyPreferredFilenameMenuItemClick,not Removed,
- Writable and (CurDependency.RequiredPackage<>nil));
- SetItem(PkgEditMenuDependencyClearStoredFileName,
- @ClearDependencyFilenameMenuItemClick,not Removed,
- Writable and (CurDependency.DefaultFilename<>''));
- end else
- PkgEditMenuSectionDependency.Visible:=false;
+ PkgEditMenuSectionDependency.Visible:=(CurDependency<>nil) or (CurNode=FRequiredPackagesNode);
+ SetItem(PkgEditMenuOpenPackage,@OpenFileMenuItemClick,
+ (CurDependency<>nil) and (CurDependency.RequiredPackage<>nil),
+ CurDependency<>nil);
+ SetItem(PkgEditMenuRemoveDependency,@RemoveBitBtnClick,
+ (CurDependency<>nil) and (not Removed),
+ RemoveBitBtn.Enabled);
+ SetItem(PkgEditMenuReAddDependency,@ReAddMenuItemClick,
+ (CurDependency<>nil) and Removed and AddBitBtn.Enabled,
+ CurDependency<>nil);
+ SetItem(PkgEditMenuDependencyStoreFileNameAsDefault,
+ @SetDependencyDefaultFilenameMenuItemClick,
+ (CurDependency<>nil) and (not Removed),
+ (CurDependency<>nil) and Writable and (CurDependency.RequiredPackage<>nil));
+ SetItem(PkgEditMenuDependencyStoreFileNameAsPreferred,
+ @SetDependencyPreferredFilenameMenuItemClick,
+ (CurDependency<>nil) and (not Removed),
+ (CurDependency<>nil) and Writable and (CurDependency.RequiredPackage<>nil));
+ SetItem(PkgEditMenuDependencyClearStoredFileName,
+ @ClearDependencyFilenameMenuItemClick,
+ (CurDependency<>nil) and (not Removed),
+ (CurDependency<>nil) and Writable and (CurDependency.RequiredPackage<>nil));
+ SetItem(PkgEditMenuCleanDependencies,
+ @CleanDependenciesMenuItemClick,LazPackage.FirstRequiredDependency<>nil,
+ Writable);
finally
PackageEditorMenuRoot.EndUpdate;
@@ -1191,6 +1208,11 @@ begin
end;
end;
+procedure TPackageEditorForm.CleanDependenciesMenuItemClick(Sender: TObject);
+begin
+ ShowCleanPkgDepDlg(LazPackage);
+end;
+
procedure TPackageEditorForm.CompileAllCleanClick(Sender: TObject);
begin
if MessageDlg(lisPckEditCompileEverything,