From ce4dc4943a06cf0c9f8939ac9d2909aed1826ae9 Mon Sep 17 00:00:00 2001 From: mattias Date: Sun, 13 Apr 2003 18:19:26 +0000 Subject: [PATCH] implemented editing dependencies git-svn-id: trunk@4055 - --- packager/brokendependenciesdlg.pas | 38 ++++++------ packager/packagedefs.pas | 14 +++-- packager/packageeditor.pas | 95 ++++++++++++++++++------------ packager/packagesystem.pas | 88 ++++++++++++++++----------- packager/pkggraphexplorer.pas | 17 ------ packager/pkgmanager.pas | 23 +++++++- 6 files changed, 159 insertions(+), 116 deletions(-) diff --git a/packager/brokendependenciesdlg.pas b/packager/brokendependenciesdlg.pas index 8353ce334b..0d05d304bb 100644 --- a/packager/brokendependenciesdlg.pas +++ b/packager/brokendependenciesdlg.pas @@ -45,8 +45,8 @@ uses type TBrokenDependenciesDialog = class(TForm) - DependencyListView: TListView; NoteLabel: TLabel; + DependencyListView: TListView; procedure BrokenDependenciesDialogClose(Sender: TObject; var Action: TCloseAction); procedure BrokenDependenciesDialogResize(Sender: TObject); @@ -122,15 +122,16 @@ var CurButton: TBitBtn; begin x:=ClientWidth; - NoteLabel.SetBounds(5,5,x-10,100); + NoteLabel.SetBounds(5,5,x-10,80); y:=NoteLabel.Top+NoteLabel.Height+2; with DependencyListView do - SetBounds(0,y,x,ClientHeight-y-40); + SetBounds(0,y,x,Parent.ClientHeight-y-40); y:=ClientHeight-35; for i:=fButtons.Count-1 downto 0 do begin CurButton:=TBitBtn(fButtons[i]); dec(x,CurButton.Width+10); - CurButton.SetBounds(x,y,Width,Height); + with CurButton do + SetBounds(x,y,80,Height); end; end; @@ -161,30 +162,28 @@ procedure TBrokenDependenciesDialog.SetupComponents; var NewColumn: TListColumn; begin + NoteLabel:=TLabel.Create(Self); + with NoteLabel do begin + Name:='NoteLabel'; + Parent:=Self; + WordWrap:=true; + Caption:='Changing the package name or version breaks dependencies. ' + +'Should these dependencies be changed as well?'#13 + +'Select Yes to change all listed dependencies.'#13 + +'Select Ignore to break the dependencies and continue.'; + end; + DependencyListView:=TListView.Create(Self); with DependencyListView do begin Name:='DependencyListView'; Parent:=Self; ViewStyle:=vsReport; NewColumn:=Columns.Add; - NewColumn.Width:=170; + NewColumn.Width:=200; NewColumn.Caption:='Package/Project'; NewColumn:=Columns.Add; NewColumn.Caption:='Dependency'; end; - - NoteLabel:=TLabel.Create(Self); - with NoteLabel do begin - Name:='NoteLabel'; - Parent:=Self; - WordWrap:=true; - Caption:='Changing the package name or version would result in breaking' - +' the dependencies listed below. Should they be changed as well?'#13 - +'Select Yes to change all listed dependencies.'#13 - +'Select Ignore to keep the dependencies untouched and continue.'#13 - +'Select Cancel to cancel the renaming and/or changing the version.'#13 - +'Select Abort to abort the current command.'; - end; end; procedure TBrokenDependenciesDialog.ClearButtons; @@ -204,7 +203,7 @@ begin SetupComponents; OnResize:=@BrokenDependenciesDialogResize; Position:=poScreenCenter; - IDEDialogLayoutList.ApplyLayout(Self,350,300); + IDEDialogLayoutList.ApplyLayout(Self,500,300); OnResize(Self); OnClose:=@BrokenDependenciesDialogClose; end; @@ -229,6 +228,7 @@ begin NewBitBtn.Name:='BitBtn'+IntToStr(fButtons.Count+1); NewBitBtn.Kind:=MsgDlgBtnToBitBtnKind[Btn]; NewBitBtn.Parent:=Self; + if Btn=mbYes then NewBitBtn.Default:=true; fButtons.Add(NewBitBtn); end; end; diff --git a/packager/packagedefs.pas b/packager/packagedefs.pas index 7cd1b06bce..5a36f622e4 100644 --- a/packager/packagedefs.pas +++ b/packager/packagedefs.pas @@ -392,7 +392,7 @@ type CompPriorityCat: TComponentPriorityCategory): TPkgFile; procedure RemoveFile(PkgFile: TPkgFile); procedure UnremovePkgFile(PkgFile: TPkgFile); - procedure UnremoveRequiredPkg(Dependency: TPkgDependency); + procedure DeleteRemoveRequiredPkg(Dependency: TPkgDependency); procedure AddRequiredDependency(Dependency: TPkgDependency); procedure RemoveRequiredDependency(Dependency: TPkgDependency); function CreateDependencyForThisPkg: TPkgDependency; @@ -881,7 +881,7 @@ procedure TPkgDependency.SetPackageName(const AValue: string); begin if FPackageName=AValue then exit; if (PackageDependencies<>nil) and (FPackageName<>'') then - PackageDependencies.Remove(Self); + PackageDependencies.RemovePointer(Self); FPackageName:=AValue; if (PackageDependencies<>nil) and (FPackageName<>'') then PackageDependencies.Add(Self); @@ -984,7 +984,13 @@ begin if Result<>0 then exit; Result:=MinVersion.Compare(Dependency2.MinVersion); if Result<>0 then exit; + Result:=CompareBoolean(pdfMinVersion in Flags, + pdfMinVersion in Dependency2.Flags); + if Result<>0 then exit; Result:=MaxVersion.Compare(Dependency2.MaxVersion); + if Result<>0 then exit; + Result:=CompareBoolean(pdfMaxVersion in Flags, + pdfMaxVersion in Dependency2.Flags); end; procedure TPkgDependency.Assign(Source: TPkgDependency); @@ -1784,10 +1790,9 @@ begin PkgFile.Removed:=false; end; -procedure TLazPackage.UnremoveRequiredPkg(Dependency: TPkgDependency); +procedure TLazPackage.DeleteRemoveRequiredPkg(Dependency: TPkgDependency); begin Dependency.RemoveFromList(FFirstRemovedDependency,pdlRequires); - Dependency.AddToList(FFirstRequiredDependency,pdlRequires); Dependency.Removed:=false; end; @@ -1795,6 +1800,7 @@ procedure TLazPackage.AddRequiredDependency(Dependency: TPkgDependency); begin Dependency.AddToList(FFirstRequiredDependency,pdlRequires); Dependency.Owner:=Self; + Modified:=true; end; procedure TLazPackage.RemoveRequiredDependency(Dependency: TPkgDependency); diff --git a/packager/packageeditor.pas b/packager/packageeditor.pas index 92c9215b06..87d93399f2 100644 --- a/packager/packageeditor.pas +++ b/packager/packageeditor.pas @@ -170,6 +170,7 @@ type function CreateNewFile(Sender: TObject; const Params: TAddToPkgResult): TModalResult; function SavePackage(APackage: TLazPackage; SaveAs: boolean): TModalResult; + procedure UpdateAllEditors; public property Editors[Index: integer]: TPackageEditorForm read GetEditors; property OnCreateNewFile: TOnCreateNewPkgFile read FOnCreateNewFile @@ -201,6 +202,7 @@ var ImageIndexRegisterUnit: integer; ImageIndexText: integer; ImageIndexBinary: integer; + ImageIndexConflict: integer; { TPackageEditorForm } @@ -270,8 +272,8 @@ begin if (Dependency<>nil) and (Removed) then begin // re-add dependency if not CheckAddingDependency(LazPackage,Dependency) then exit; - LazPackage.UnremoveRequiredPkg(Dependency); - UpdateAll; + LazPackage.DeleteRemoveRequiredPkg(Dependency); + PackageGraph.AddDependencyToPackage(LazPackage,Dependency); end; end; end; @@ -605,7 +607,7 @@ begin d2ptRequiredPkg: begin // add dependency - LazPackage.AddRequiredDependency(AddParams.Dependency); + PackageGraph.AddDependencyToPackage(LazPackage,AddParams.Dependency); end; end; @@ -620,44 +622,47 @@ var Removed: boolean; NewDependency: TPkgDependency; begin - NewDependency:=TPkgDependency.Create; - - // read minimum version - if UseMinVersionCheckBox.Checked then begin - NewDependency.Flags:=NewDependency.Flags+[pdfMinVersion]; - if not NewDependency.MinVersion.ReadString(MinVersionEdit.Text) then begin - MessageDlg('Invalid minimum version', - 'The minimum version "'+MinVersionEdit.Text+'" ' - +'is not a valid package version.'#13 - +'(good example 1.2.3.4)', - mtError,[mbCancel],0); - exit; - end; - end else begin - NewDependency.Flags:=NewDependency.Flags-[pdfMinVersion]; - end; - - // read maximum version - if UseMaxVersionCheckBox.Checked then begin - NewDependency.Flags:=NewDependency.Flags+[pdfMaxVersion]; - if not NewDependency.MaxVersion.ReadString(MaxVersionEdit.Text) then begin - MessageDlg('Invalid maximum version', - 'The maximum version "'+MaxVersionEdit.Text+'" ' - +'is not a valid package version.'#13 - +'(good example 1.2.3.4)', - mtError,[mbCancel],0); - exit; - end; - end else begin - NewDependency.Flags:=NewDependency.Flags-[pdfMaxVersion]; - end; - CurDependency:=GetCurrentDependency(Removed); if (CurDependency=nil) or Removed then exit; - - PackageGraph.ChangeDependency(CurDependency,NewDependency); - NewDependency.Free; + NewDependency:=TPkgDependency.Create; + try + NewDependency.Assign(CurDependency); + + // read minimum version + if UseMinVersionCheckBox.Checked then begin + NewDependency.Flags:=NewDependency.Flags+[pdfMinVersion]; + if not NewDependency.MinVersion.ReadString(MinVersionEdit.Text) then begin + MessageDlg('Invalid minimum version', + 'The minimum version "'+MinVersionEdit.Text+'" ' + +'is not a valid package version.'#13 + +'(good example 1.2.3.4)', + mtError,[mbCancel],0); + exit; + end; + end else begin + NewDependency.Flags:=NewDependency.Flags-[pdfMinVersion]; + end; + + // read maximum version + if UseMaxVersionCheckBox.Checked then begin + NewDependency.Flags:=NewDependency.Flags+[pdfMaxVersion]; + if not NewDependency.MaxVersion.ReadString(MaxVersionEdit.Text) then begin + MessageDlg('Invalid maximum version', + 'The maximum version "'+MaxVersionEdit.Text+'" ' + +'is not a valid package version.'#13 + +'(good example 1.2.3.4)', + mtError,[mbCancel],0); + exit; + end; + end else begin + NewDependency.Flags:=NewDependency.Flags-[pdfMaxVersion]; + end; + + PackageGraph.ChangeDependency(CurDependency,NewDependency); + finally + NewDependency.Free; + end; end; procedure TPackageEditorForm.CallRegisterProcCheckBoxClick(Sender: TObject); @@ -771,6 +776,8 @@ begin AddResImg('pkg_text'); ImageIndexBinary:=Count; AddResImg('pkg_binary'); + ImageIndexConflict:=Count; + AddResImg('pkg_conflict'); end; SaveBitBtn:=TBitBtn.Create(Self); @@ -1086,7 +1093,10 @@ begin if CurNode=nil then CurNode:=FilesTreeView.Items.AddChild(RequiredPackagesNode,''); CurNode.Text:=CurDependency.AsString; - CurNode.ImageIndex:=RequiredPackagesNode.ImageIndex; + if CurDependency.LoadPackageResult=lprSuccess then + CurNode.ImageIndex:=ImageIndexRequired + else + CurNode.ImageIndex:=ImageIndexConflict; CurNode.SelectedIndex:=CurNode.ImageIndex; CurNode:=CurNode.GetNextSibling; CurDependency:=CurDependency.NextRequiresDependency; @@ -1417,6 +1427,13 @@ begin if Assigned(OnSavePackage) then Result:=OnSavePackage(Self,APackage,SaveAs); end; +procedure TPackageEditors.UpdateAllEditors; +var + i: Integer; +begin + for i:=0 to Count-1 do Editors[i].UpdateAll; +end; + initialization PackageEditors:=nil; diff --git a/packager/packagesystem.pas b/packager/packagesystem.pas index 264dee81f8..a58c644f21 100644 --- a/packager/packagesystem.pas +++ b/packager/packagesystem.pas @@ -54,6 +54,7 @@ type fpfSearchInInstalledPckgs, fpfSearchInAutoInstallPckgs, fpfSearchInPckgsWithEditor, + fpfSearchInLoadedPkgs, fpfSearchInPkgLinks, fpfIgnoreVersion ); @@ -62,13 +63,13 @@ type const fpfSearchPackageEverywhere = [fpfSearchInInstalledPckgs,fpfSearchInAutoInstallPckgs, - fpfSearchInPckgsWithEditor,fpfSearchInPkgLinks]; + fpfSearchInPckgsWithEditor,fpfSearchInPkgLinks,fpfSearchInLoadedPkgs]; type TPkgAddedEvent = procedure(APackage: TLazPackage) of object; TPkgDeleteEvent = procedure(APackage: TLazPackage) of object; TDependencyModifiedEvent = procedure(ADependency: TPkgDependency) of object; - TEndUpdateEvent = procedure(Sender: TObject; Changed: boolean) of object; + TEndUpdateEvent = procedure(Sender: TObject; GraphChanged: boolean) of object; TLazPackageGraph = class private @@ -95,6 +96,7 @@ type procedure DoDependencyChanged(Dependency: TPkgDependency); procedure SetAbortRegistration(const AValue: boolean); procedure SetRegistrationPackage(const AValue: TLazPackage); + procedure UpdateBrokenDependenciesToPackage(APackage: TLazPackage); public constructor Create; destructor Destroy; override; @@ -146,6 +148,8 @@ type function CheckIfPackageCanBeClosed(APackage: TLazPackage): boolean; function PackageIsNeeded(APackage: TLazPackage): boolean; procedure RegisterStaticPackages; + procedure AddDependencyToPackage(APackage: TLazPackage; + Dependency: TPkgDependency); procedure ChangeDependency(Dependency, NewDependency: TPkgDependency); function OpenDependency(Dependency: TPkgDependency; var APackage: TLazPackage): TLoadPackageResult; @@ -225,6 +229,27 @@ begin RegisterNoIconProc:=@RegisterNoIconGlobalHandler; end; +procedure TLazPackageGraph.UpdateBrokenDependenciesToPackage( + APackage: TLazPackage); +var + ANode: TAVLTreeNode; + Dependency: TPkgDependency; + RequiredPackage: TLazPackage; +begin + BeginUpdate(false); + ANode:=FindLowestPkgDependencyNodeWithName(APackage.Name); + while ANode<>nil do begin + Dependency:=TPkgDependency(ANode.Data); + if (Dependency.LoadPackageResult<>lprSuccess) + and Dependency.IsCompatible(APackage) then begin + Dependency.LoadPackageResult:=lprUndefined; + OpenDependency(Dependency,RequiredPackage); + end; + ANode:=FindNextPkgDependecyNodeWithSameName(ANode); + end; + EndUpdate; +end; + constructor TLazPackageGraph.Create; begin FTree:=TAVLTree.Create(@CompareLazPackageID); @@ -274,8 +299,8 @@ end; procedure TLazPackageGraph.BeginUpdate(Change: boolean); begin inc(FUpdateLock); - fChanged:=Change; if FUpdateLock=1 then begin + fChanged:=Change; if Assigned(OnBeginUpdate) then OnBeginUpdate(Self); end; end; @@ -340,6 +365,8 @@ begin Result:=FindNextSameName(Result); continue; end; + // check loaded packages + if (fpfSearchInLoadedPkgs in Flags) then exit; // check installed packages if (fpfSearchInInstalledPckgs in Flags) and (CurPkg.Installed<>pitNope) then exit; @@ -737,13 +764,12 @@ procedure TLazPackageGraph.AddPackage(APackage: TLazPackage); var RequiredPackage: TLazPackage; Dependency: TPkgDependency; - DepNode: TAVLTreeNode; begin BeginUpdate(true); FTree.Add(APackage); FItems.Add(APackage); - // open all dependencies + // open all required dependencies Dependency:=APackage.FirstRequiredDependency; while Dependency<>nil do begin OpenDependency(Dependency,RequiredPackage); @@ -751,17 +777,8 @@ begin end; // update all missing dependencies - DepNode:=FindLowestPkgDependencyNodeWithName(APackage.Name); - while DepNode<>nil do begin - Dependency:=TPkgDependency(DepNode.Data); - if (Dependency.LoadPackageResult<>lprSuccess) - and Dependency.IsCompatible(APackage) then begin - Dependency.RequiredPackage:=APackage; - Dependency.LoadPackageResult:=lprSuccess; - end; - DepNode:=FindNextPkgDependecyNodeWithSameName(DepNode); - end; - + UpdateBrokenDependenciesToPackage(APackage); + if Assigned(OnAddPackage) then OnAddPackage(APackage); EndUpdate; end; @@ -849,9 +866,7 @@ end; procedure TLazPackageGraph.ChangePackageID(APackage: TLazPackage; const NewName: string; NewVersion: TPkgVersion; RenameDependencies: boolean); var - Dependency, FirstUpdateDependency: TPkgDependency; - RequiredPackage: TLazPackage; - ANode: TAVLTreeNode; + Dependency: TPkgDependency; NextDependency: TPkgDependency; OldPkgName: String; begin @@ -869,9 +884,8 @@ begin BeginUpdate(true); - // break or change all dependencies, that became incompatible + // cut or fix all dependencies, that became incompatible Dependency:=APackage.FirstUsedByDependency; - FirstUpdateDependency:=nil; while Dependency<>nil do begin NextDependency:=Dependency.NextUsedByDependency; if not Dependency.IsCompatible(NewName,NewVersion) then begin @@ -879,8 +893,8 @@ begin Dependency.MakeCompatible(NewName,NewVersion); if Assigned(OnDependencyModified) then OnDependencyModified(Dependency); end else begin + // remove dependency from the used-by list of the required package Dependency.RequiredPackage:=nil; - Dependency.AddToList(FirstUpdateDependency,pdlUsedBy); end; end; Dependency:=NextDependency; @@ -891,21 +905,9 @@ begin APackage.ChangeID(NewName,NewVersion); FTree.Add(APackage); - // update new broken dependencies - while FirstUpdateDependency<>nil do begin - Dependency.RemoveFromList(FirstUpdateDependency,pdlUsedBy); - OpenDependency(Dependency,RequiredPackage); - end; // update old broken dependencies - ANode:=FindLowestPkgDependencyNodeWithName(NewName); - while ANode<>nil do begin - Dependency:=TPkgDependency(ANode.Data); - if (Dependency.LoadPackageResult<>lprSuccess) - and Dependency.IsCompatible(APackage) then - OpenDependency(Dependency,RequiredPackage); - ANode:=FindNextPkgDependecyNodeWithSameName(ANode); - end; - + UpdateBrokenDependenciesToPackage(APackage); + if Assigned(OnChangePackageName) then OnChangePackageName(APackage,OldPkgName); EndUpdate; @@ -968,6 +970,18 @@ begin RegistrationPackage:=nil; end; +procedure TLazPackageGraph.AddDependencyToPackage(APackage: TLazPackage; + Dependency: TPkgDependency); +var + RequiredPackage: TLazPackage; +begin + BeginUpdate(true); + APackage.AddRequiredDependency(Dependency); + Dependency.LoadPackageResult:=lprUndefined; + OpenDependency(Dependency,RequiredPackage); + EndUpdate; +end; + procedure TLazPackageGraph.ChangeDependency(Dependency, NewDependency: TPkgDependency); var @@ -976,6 +990,7 @@ begin if Dependency.Compare(NewDependency)=0 then exit; BeginUpdate(true); Dependency.Assign(NewDependency); + Dependency.LoadPackageResult:=lprUndefined; OpenDependency(Dependency,RequiredPackage); DoDependencyChanged(Dependency); EndUpdate; @@ -1009,6 +1024,7 @@ begin Dependency.RequiredPackage:=nil; Dependency.LoadPackageResult:=lprNotFound; end; + fChanged:=true; EndUpdate; end; APackage:=Dependency.RequiredPackage; diff --git a/packager/pkggraphexplorer.pas b/packager/pkggraphexplorer.pas index 2cd8e133c7..72f8810a95 100644 --- a/packager/pkggraphexplorer.pas +++ b/packager/pkggraphexplorer.pas @@ -51,8 +51,6 @@ type PkgListLabel: TLabel; PkgListBox: TListBox; InfoMemo: TMemo; - procedure PackageGraphBeginUpdate(Sender: TObject); - procedure PkgGraphExplorerEndUpdate(Sender: TObject; GraphChanged: boolean); procedure PkgGraphExplorerResize(Sender: TObject); procedure PkgGraphExplorerShow(Sender: TObject); procedure PkgListBoxClick(Sender: TObject); @@ -229,18 +227,6 @@ begin SetBounds(x,y,Parent.ClientWidth-2*x,Max(10,Parent.ClientHeight-y-x)); end; -procedure TPkgGraphExplorer.PackageGraphBeginUpdate(Sender: TObject); -begin - BeginUpdate; -end; - -procedure TPkgGraphExplorer.PkgGraphExplorerEndUpdate(Sender: TObject; - GraphChanged: boolean); -begin - if GraphChanged then UpdateAll; - EndUpdate; -end; - procedure TPkgGraphExplorer.PkgGraphExplorerShow(Sender: TObject); begin UpdateAll; @@ -493,9 +479,6 @@ begin OnResize:=@PkgGraphExplorerResize; OnResize(Self); OnShow:=@PkgGraphExplorerShow; - - PackageGraph.OnBeginUpdate:=@PackageGraphBeginUpdate; - PackageGraph.OnEndUpdate:=@PkgGraphExplorerEndUpdate; end; destructor TPkgGraphExplorer.Destroy; diff --git a/packager/pkgmanager.pas b/packager/pkgmanager.pas index 49ffd8e5fc..ca173e3579 100644 --- a/packager/pkgmanager.pas +++ b/packager/pkgmanager.pas @@ -66,6 +66,7 @@ type ): TModalResult; function OnPackageEditorSavePackage(Sender: TObject; APackage: TLazPackage; SaveAs: boolean): TModalResult; + procedure PackageGraphBeginUpdate(Sender: TObject); procedure PackageGraphChangePackageName(APackage: TLazPackage; const OldName: string); procedure PackageGraphDeletePackage(APackage: TLazPackage); @@ -73,6 +74,7 @@ type function PackageGraphExplorerOpenPackage(Sender: TObject; APackage: TLazPackage): TModalResult; procedure PkgManagerAddPackage(Pkg: TLazPackage); + procedure PkgManagerEndUpdate(Sender: TObject; GraphChanged: boolean); procedure mnuConfigCustomCompsClicked(Sender: TObject); procedure mnuPkgOpenPackageClicked(Sender: TObject); procedure mnuOpenRecentPackageClicked(Sender: TObject); @@ -235,6 +237,11 @@ begin Result:=DoSavePackage(APackage,[]); end; +procedure TPkgManager.PackageGraphBeginUpdate(Sender: TObject); +begin + if PackageGraphExplorer<>nil then PackageGraphExplorer.BeginUpdate; +end; + procedure TPkgManager.PackageGraphChangePackageName(APackage: TLazPackage; const OldName: string); begin @@ -274,6 +281,18 @@ begin PackageGraphExplorer.UpdatePackageAdded(Pkg); end; +procedure TPkgManager.PkgManagerEndUpdate(Sender: TObject; GraphChanged: boolean); +begin + if PackageGraphExplorer<>nil then begin + if GraphChanged then PackageGraphExplorer.UpdateAll; + PackageGraphExplorer.EndUpdate; + end; + if GraphChanged then begin + if PackageEditors<>nil then + PackageEditors.UpdateAllEditors; + end; +end; + procedure TPkgManager.mnuConfigCustomCompsClicked(Sender: TObject); begin ShowConfigureCustomComponents; @@ -498,7 +517,9 @@ begin PackageGraph.OnAddPackage:=@PkgManagerAddPackage; PackageGraph.OnDeletePackage:=@PackageGraphDeletePackage; PackageGraph.OnDependencyModified:=@PackageGraphDependencyModified; - + PackageGraph.OnBeginUpdate:=@PackageGraphBeginUpdate; + PackageGraph.OnEndUpdate:=@PkgManagerEndUpdate; + PackageEditors:=TPackageEditors.Create; PackageEditors.OnOpenFile:=@MainIDE.DoOpenMacroFile; PackageEditors.OnOpenPackage:=@OnPackageEditorOpenPackage;