IdeIntf: Separate an interface for PackageLinks.

git-svn-id: trunk@54407 -
This commit is contained in:
juha 2017-03-15 13:13:41 +00:00
parent 6157074807
commit a2d555718e
9 changed files with 217 additions and 122 deletions

1
.gitattributes vendored
View File

@ -1871,6 +1871,7 @@ components/ideintf/objinspstrconsts.pas svneol=native#text/pascal
components/ideintf/oifavoriteproperties.pas svneol=native#text/pascal
components/ideintf/packagedependencyintf.pas svneol=native#text/pascal
components/ideintf/packageintf.pas svneol=native#text/pascal
components/ideintf/packagelinkintf.pas svneol=native#text/pascal
components/ideintf/pagespropeditdlg.lfm svneol=native#text/plain
components/ideintf/pagespropeditdlg.pas svneol=native#text/pascal
components/ideintf/projectintf.pas svneol=native#text/pascal

View File

@ -20,7 +20,7 @@
<Description Value="IDEIntf - the interface units for the Lazarus IDE"/>
<License Value="Modified LGPL2"/>
<Version Major="1"/>
<Files Count="82">
<Files Count="83">
<Item1>
<Filename Value="actionseditor.pas"/>
<UnitName Value="ActionsEditor"/>
@ -350,6 +350,10 @@
<Filename Value="packagedependencyintf.pas"/>
<UnitName Value="PackageDependencyIntf"/>
</Item82>
<Item83>
<Filename Value="packagelinkintf.pas"/>
<UnitName Value="PackageLinkIntf"/>
</Item83>
</Files>
<LazDoc Paths="docs"/>
<i18n>

View File

@ -22,7 +22,7 @@ uses
ProjectIntf, ProjectResourcesIntf, PropEdits, PropEditUtils, SrcEditorIntf,
StatusBarPropEdit, StringsPropEditDlg, TextTools, TreeViewPropEdit,
UnitResources, ProjPackIntf, DBGridColumnsPropEditForm, ToolBarIntf,
ChangeParentDlg, PackageDependencyIntf, LazarusPackageIntf;
ChangeParentDlg, PackageDependencyIntf, PackageLinkIntf, LazarusPackageIntf;
implementation

View File

@ -0,0 +1,126 @@
unit PackageLinkIntf;
{$mode objfpc}{$H+}
interface
uses
SysUtils,
// LazUtils
LazFileUtils,
// IdeIntf
PackageDependencyIntf, PackageIntf;
type
{ TPackageLink
There are several types of package links.
Global: These are collected from the lazarus source directory.
EnvironmentOptions.LazarusDirectory+'packager/globallinks/*.lpl'
This way packages can install/uninstall themselves to one lazarus
source directory, and this lazarus directory can then be shared
by several users/configs.
User: These are collected from the user config directory, from the file
packagelinks.xml.
These links are maintained by the IDE. Everytime the user opens a
package a user link is created, so that the next time the package
can be automatically opened. The list is checked by the IDE from
time to time and missing packages are first marked and after several
months deleted from the list.
Relative files are expanded with the Lazarus directory.
}
TPkgLinkOrigin = (
ploGlobal,
ploUser
);
TPkgLinkOrigins = set of TPkgLinkOrigin;
const
AllPkgLinkOrigins = [low(TPkgLinkOrigin)..high(TPkgLinkOrigin)];
type
{ TPackageLink }
TPackageLink = class(TLazPackageID)
private
procedure SetFilename(const AValue: string);
protected
FFileDate: TDateTime;
FFileDateValid: boolean;
FFilename: string;
FLPLFileDate: TDateTime;
FLPLFilename: string;
FOrigin: TPkgLinkOrigin;
FLastUsed: TDateTime;
public
constructor Create; override;
destructor Destroy; override;
function IsMakingSense: boolean;
function GetEffectiveFilename: string; virtual; abstract;
procedure Reference; virtual; abstract;
procedure Release; virtual; abstract;
public
property LPKFileDateValid: boolean read FFileDateValid write FFileDateValid;
property LPKFileDate: TDateTime read FFileDate write FFileDate;
property LPKFilename: string read FFilename write SetFilename; // if relative it is relative to the LazarusDir
property LPLFilename: string read FLPLFilename write FLPLFilename;
property LPLFileDate: TDateTime read FLPLFileDate write FLPLFileDate;
property Origin: TPkgLinkOrigin read FOrigin write FOrigin;
property LastUsed: TDateTime read FLastUsed write FLastUsed;
end;
{ TPackageLinks }
TPackageLinks = class
private
public
function FindLinkWithPkgName(const PkgName: string): TPackageLink; virtual; abstract;
function FindLinkWithDependency(Dependency: TPkgDependencyID): TPackageLink; virtual; abstract;
function FindLinkWithPackageID(APackageID: TLazPackageID): TPackageLink; virtual; abstract;
function FindLinkWithFilename(const PkgName, LPKFilename: string): TPackageLink; virtual; abstract;
procedure IteratePackages(MustExist: boolean; Event: TIteratePackagesEvent;
Origins: TPkgLinkOrigins = AllPkgLinkOrigins); virtual; abstract;
function AddUserLink(APackage: TIDEPackage): TPackageLink; virtual; abstract;
// do not use this if package is open in IDE
function AddUserLink(const PkgFilename, PkgName: string): TPackageLink; virtual; abstract;
procedure RemoveUserLink(Link: TPackageLink); virtual; abstract;
procedure RemoveUserLinks(APackageID: TLazPackageID); virtual; abstract;
end;
var
PkgLinks: TPackageLinks;
implementation
{ TPackageLink }
constructor TPackageLink.Create;
begin
inherited Create;
end;
destructor TPackageLink.Destroy;
begin
inherited Destroy;
end;
procedure TPackageLink.SetFilename(const AValue: string);
begin
if FFilename=AValue then exit;
FFilename:=TrimFilename(AValue);
end;
function TPackageLink.IsMakingSense: boolean;
begin
Result:=IsValidPkgName(Name)
and PackageFileNameIsValid(LPKFilename)
and (CompareText(Name,ExtractFileNameOnly(LPKFilename))=0);
end;
end.

View File

@ -39,7 +39,7 @@ uses
// codetools
CodeToolsStrConsts, CodeCache, CodeToolManager,
// IDEIntf
LazIDEIntf, IDEMsgIntf, PackageIntf, IDEExternToolIntf,
LazIDEIntf, IDEMsgIntf, PackageLinkIntf, PackageIntf, IDEExternToolIntf,
// IDE
DialogProcs, PackageDefs, Project, IDEProcs, LazarusIDEStrConsts,
etFPCMsgParser, PackageLinks, PackageSystem, BasePkgManager;

View File

@ -47,7 +47,7 @@ uses
// Codetools
FileProcs, CodeToolManager, CodeToolsStructs,
// IdeIntf
MacroIntf, PackageDependencyIntf, PackageIntf,
MacroIntf, PackageDependencyIntf, PackageLinkIntf, PackageIntf,
// IDE
IDEProcs, EnvironmentOpts, LazConf, IDECmdLine, PackageDefs;
@ -57,64 +57,18 @@ const
after IDE restart }
type
{ TLazPackageLink
There are several types of package links.
Global: These are collected from the lazarus source directory.
EnvironmentOptions.LazarusDirectory+'packager/globallinks/*.lpl'
This way packages can install/uninstall themselves to one lazarus
source directory, and this lazarus directory can then be shared
by several users/configs.
User: These are collected from the user config directory, from the file
packagelinks.xml.
These links are maintained by the IDE. Everytime the user opens a
package a user link is created, so that the next time the package
can be automatically opened. The list is checked by the IDE from
time to time and missing packages are first marked and after several
months deleted from the list.
Relative files are expanded with the Lazarus directory.
}
TPkgLinkOrigin = (
ploGlobal,
ploUser
);
TPkgLinkOrigins = set of TPkgLinkOrigin;
const
AllPkgLinkOrigins = [low(TPkgLinkOrigin)..high(TPkgLinkOrigin)];
type
TLazPackageLink = class(TLazPackageID)
TLazPackageLink = class(TPackageLink)
private
FAutoCheckExists: boolean;
FFileDate: TDateTime;
FFileDateValid: boolean;
FFilename: string;
FLastUsed: TDateTime;
FLPLFileDate: TDateTime;
FLPLFilename: string;
FOrigin: TPkgLinkOrigin;
fReferenceCount: integer;
procedure SetFilename(const AValue: string);
public
constructor Create; override;
destructor Destroy; override;
function IsMakingSense: boolean;
function GetEffectiveFilename: string;
procedure Reference;
procedure Release;
function GetEffectiveFilename: string; override;
procedure Reference; override;
procedure Release; override;
public
property Origin: TPkgLinkOrigin read FOrigin write FOrigin;
property LPKFilename: string read FFilename write SetFilename; // if relative it is relative to the LazarusDir
property LPLFilename: string read FLPLFilename write FLPLFilename;
property LPLFileDate: TDateTime read FLPLFileDate write FLPLFileDate;
property AutoCheckExists: boolean read FAutoCheckExists write FAutoCheckExists;
property LPKFileDateValid: boolean read FFileDateValid write FFileDateValid;
property LPKFileDate: TDateTime read FFileDate write FFileDate;
property LastUsed: TDateTime read FLastUsed write FLastUsed;
end;
{ TLazPackageLinks }
@ -127,7 +81,7 @@ type
);
TPkgLinksStates = set of TPkgLinksState;
TLazPackageLinks = class
TLazPackageLinks = class(TPackageLinks)
private
FGlobalLinks: TAvgLvlTree; // tree of global TLazPackageLink sorted for ID
FChangeStamp: integer;
@ -173,19 +127,22 @@ type
procedure SaveUserLinks(Immediately: boolean = false);
function NeedSaveUserLinks(const ConfigFilename: string): boolean;
procedure WriteLinkTree(LinkTree: TAvgLvlTree);
function FindLinkWithPkgName(const PkgName: string;
IgnoreFiles: TFilenameToStringTree = nil): TLazPackageLink;
function FindLinkWithDependency(Dependency: TPkgDependencyID;
IgnoreFiles: TFilenameToStringTree = nil): TLazPackageLink;
function FindLinkWithPackageID(APackageID: TLazPackageID): TLazPackageLink;
function FindLinkWithFilename(const PkgName, LPKFilename: string): TLazPackageLink;
procedure IteratePackages(MustExist: boolean; Event: TIteratePackagesEvent;
Origins: TPkgLinkOrigins = AllPkgLinkOrigins);
function AddUserLink(APackage: TIDEPackage): TLazPackageLink;
function AddUserLink(const PkgFilename, PkgName: string): TLazPackageLink;// do not use this if package is open in IDE
procedure RemoveUserLink(Link: TLazPackageLink);
procedure RemoveUserLinks(APackageID: TLazPackageID);
procedure IncreaseChangeStamp;
// Methods defined as interface in TLazPackageLinks.
function FindLinkWithPkgName(const PkgName: string): TPackageLink; override;
function FindLinkWithPkgNameWithIgnore(const PkgName: string;
IgnoreFiles: TFilenameToStringTree): TPackageLink;
function FindLinkWithDependency(Dependency: TPkgDependencyID): TPackageLink; override;
function FindLinkWithDependencyWithIgnore(Dependency: TPkgDependencyID;
IgnoreFiles: TFilenameToStringTree): TPackageLink;
function FindLinkWithPackageID(APackageID: TLazPackageID): TPackageLink; override;
function FindLinkWithFilename(const PkgName, LPKFilename: string): TPackageLink; override;
procedure IteratePackages(MustExist: boolean; Event: TIteratePackagesEvent;
Origins: TPkgLinkOrigins = AllPkgLinkOrigins); override;
function AddUserLink(APackage: TIDEPackage): TPackageLink; override;
function AddUserLink(const PkgFilename, PkgName: string): TPackageLink; override;
procedure RemoveUserLink(Link: TPackageLink); override;
procedure RemoveUserLinks(APackageID: TLazPackageID); override;
public
property Modified: boolean read GetModified write SetModified;
property ChangeStamp: integer read FChangeStamp;
@ -287,12 +244,6 @@ end;
{ TLazPackageLink }
procedure TLazPackageLink.SetFilename(const AValue: string);
begin
if FFilename=AValue then exit;
FFilename:=TrimFilename(AValue);
end;
constructor TLazPackageLink.Create;
begin
inherited Create;
@ -306,13 +257,6 @@ begin
inherited Destroy;
end;
function TLazPackageLink.IsMakingSense: boolean;
begin
Result:=IsValidPkgName(Name)
and PackageFileNameIsValid(LPKFilename)
and (CompareText(Name,ExtractFileNameOnly(LPKFilename))=0);
end;
function TLazPackageLink.GetEffectiveFilename: string;
begin
Result:=LPKFilename;
@ -377,6 +321,7 @@ end;
constructor TLazPackageLinks.Create;
begin
PkgLinks:=Self;
UserLinkLoadTimeValid:=false;
FGlobalLinks:=TAvgLvlTree.Create(@ComparePackageLinks);
FUserLinksSortID:=TAvgLvlTree.Create(@ComparePackageLinks);
@ -1148,8 +1093,13 @@ begin
Application.RemoveAsyncCalls(Self);
end;
function TLazPackageLinks.FindLinkWithPkgName(const PkgName: string;
IgnoreFiles: TFilenameToStringTree): TLazPackageLink;
function TLazPackageLinks.FindLinkWithPkgName(const PkgName: string): TPackageLink;
begin
Result := FindLinkWithPkgNameWithIgnore(PkgName, Nil);
end;
function TLazPackageLinks.FindLinkWithPkgNameWithIgnore(const PkgName: string;
IgnoreFiles: TFilenameToStringTree): TPackageLink;
var
UserLink, GlobalLink: TLazPackageLink;
begin
@ -1158,8 +1108,13 @@ begin
Result:=GetNewerLink(UserLink,GlobalLink);
end;
function TLazPackageLinks.FindLinkWithDependency(Dependency: TPkgDependencyID;
IgnoreFiles: TFilenameToStringTree): TLazPackageLink;
function TLazPackageLinks.FindLinkWithDependency(Dependency: TPkgDependencyID): TPackageLink;
begin
Result := FindLinkWithDependencyWithIgnore(Dependency, Nil);
end;
function TLazPackageLinks.FindLinkWithDependencyWithIgnore(Dependency: TPkgDependencyID;
IgnoreFiles: TFilenameToStringTree): TPackageLink;
var
UserLink, GlobalLink: TLazPackageLink;
begin
@ -1168,8 +1123,7 @@ begin
Result:=GetNewerLink(UserLink,GlobalLink);
end;
function TLazPackageLinks.FindLinkWithPackageID(APackageID: TLazPackageID
): TLazPackageLink;
function TLazPackageLinks.FindLinkWithPackageID(APackageID: TLazPackageID): TPackageLink;
var
UserLink, GlobalLink: TLazPackageLink;
begin
@ -1178,8 +1132,7 @@ begin
Result:=GetNewerLink(UserLink,GlobalLink);
end;
function TLazPackageLinks.FindLinkWithFilename(const PkgName, LPKFilename: string
): TLazPackageLink;
function TLazPackageLinks.FindLinkWithFilename(const PkgName, LPKFilename: string): TPackageLink;
var
UserLink, GlobalLink: TLazPackageLink;
begin
@ -1197,10 +1150,10 @@ begin
IteratePackagesInTree(MustExist,FGlobalLinks,Event);
end;
function TLazPackageLinks.AddUserLink(APackage: TIDEPackage): TLazPackageLink;
function TLazPackageLinks.AddUserLink(APackage: TIDEPackage): TPackageLink;
var
OldLink: TLazPackageLink;
NewLink: TLazPackageLink;
OldLink: TPackageLink;
NewLink: TPackageLink;
begin
BeginUpdate;
try
@ -1237,10 +1190,10 @@ begin
end;
end;
function TLazPackageLinks.AddUserLink(const PkgFilename, PkgName: string): TLazPackageLink;
function TLazPackageLinks.AddUserLink(const PkgFilename, PkgName: string): TPackageLink;
var
OldLink: TLazPackageLink;
NewLink: TLazPackageLink;
OldLink: TPackageLink;
NewLink: TPackageLink;
LPK: TXMLConfig;
PkgVersion: TPkgVersion;
begin
@ -1289,7 +1242,7 @@ begin
end;
end;
procedure TLazPackageLinks.RemoveUserLink(Link: TLazPackageLink);
procedure TLazPackageLinks.RemoveUserLink(Link: TPackageLink);
var
ANode: TAvgLvlTreeNode;
begin

View File

@ -41,20 +41,23 @@ interface
{$DEFINE StopOnRegError}
uses
{$IFDEF IDE_MEM_CHECK}
{$IFDEF IDE_MEM_CHECK}
MemCheck,
{$ENDIF}
// FPC + LCL
Classes, SysUtils, strutils, Forms, Controls, Dialogs,
FileProcs, FileUtil, LCLProc, LazFileCache,
Laz2_XMLCfg, LazLogger, LazFileUtils, LazUTF8, laz2_XMLRead,
{$ENDIF}
// FPC
Classes, SysUtils, contnrs, strutils, AVL_Tree,
// LCL
Forms, Controls, Dialogs, LCLProc,
// LazUtils
FileUtil, LazFileCache, LazLogger, LazFileUtils, LazUTF8,
Laz2_XMLCfg, laz2_XMLRead, AvgLvlTree,
// codetools
AVL_Tree, contnrs, DefineTemplates, CodeCache,
BasicCodeTools, CodeToolsStructs, NonPascalCodeTools, SourceChanger,
FileProcs, DefineTemplates, CodeCache,
BasicCodeTools, NonPascalCodeTools, SourceChanger, CodeToolsStructs,
CodeToolManager, DirectoryCacher,
// IDEIntf,
IDEExternToolIntf, IDEDialogs, IDEMsgIntf, PackageDependencyIntf, PackageIntf,
CompOptsIntf, LazIDEIntf, MacroDefIntf, ProjectIntf, LazarusPackageIntf,
IDEExternToolIntf, IDEDialogs, IDEMsgIntf, CompOptsIntf, LazIDEIntf, MacroDefIntf,
ProjectIntf, PackageDependencyIntf, PackageLinkIntf, PackageIntf, LazarusPackageIntf,
// IDE
LazarusIDEStrConsts, IDECmdLine, EnvironmentOpts, IDEProcs, LazConf,
TransferMacros, DialogProcs, IDETranslations, CompilerOptions, PackageLinks,
@ -216,7 +219,7 @@ type
procedure SetRegistrationPackage(const AValue: TLazPackage);
procedure UpdateBrokenDependenciesToPackage(APackage: TLazPackage);
function OpenDependencyWithPackageLink(Dependency: TPkgDependency;
PkgLink: TLazPackageLink; ShowAbort: boolean): TModalResult;
PkgLink: TPackageLink; ShowAbort: boolean): TModalResult;
function DeleteAmbiguousFiles(const Filename: string): TModalResult;
procedure AddMessage(TheUrgency: TMessageLineUrgency; const Msg, Filename: string);
function OutputDirectoryIsWritable(APackage: TLazPackage; Directory: string;
@ -922,8 +925,9 @@ begin
EndUpdate;
end;
function TLazPackageGraph.OpenDependencyWithPackageLink(Dependency: TPkgDependency;
PkgLink: TLazPackageLink; ShowAbort: boolean): TModalResult;
function TLazPackageGraph.OpenDependencyWithPackageLink(
Dependency: TPkgDependency; PkgLink: TPackageLink; ShowAbort: boolean
): TModalResult;
var
AFilename: String;
NewPackage: TLazPackage;
@ -5535,9 +5539,9 @@ function TLazPackageGraph.OpenDependency(Dependency: TPkgDependency;
procedure OpenFile(AFilename: string);
var
PkgLink: TLazPackageLink;
PkgLink: TPackageLink;
begin
PkgLink:=LazPackageLinks.AddUserLink(AFilename,Dependency.PackageName);
PkgLink:=LazPackageLinks.AddUserLink(AFilename, Dependency.PackageName);
if (PkgLink<>nil) then begin
PkgLink.Reference;
try
@ -5556,7 +5560,7 @@ var
MsgResult: TModalResult;
APackage: TLazPackage;
PreferredFilename: string;
PkgLink: TLazPackageLink;
PkgLink: TPackageLink;
IgnoreFiles: TFilenameToStringTree;
i: Integer;
begin
@ -5601,7 +5605,7 @@ begin
IgnoreFiles:=nil;
try
repeat
PkgLink:=LazPackageLinks.FindLinkWithDependency(Dependency,IgnoreFiles);
PkgLink:=LazPackageLinks.FindLinkWithDependencyWithIgnore(Dependency,IgnoreFiles);
if (PkgLink=nil) then break;
//debugln(['TLazPackageGraph.OpenDependency PkgLink=',PkgLink.GetEffectiveFilename,' global=',PkgLink.Origin=ploGlobal]);
PkgLink.Reference;
@ -5732,7 +5736,7 @@ var
var
Dependency: TPkgDependency;
Version: TPkgVersion;
PkgLink: TLazPackageLink;
PkgLink: TPackageLink;
Filename: String;
BaseDir: String;
begin
@ -5761,7 +5765,7 @@ begin
Result:='';
BaseDir:=TrimFilename(APackage.Directory);
repeat
PkgLink:=LazPackageLinks.FindLinkWithDependency(Dependency,IgnoreFiles);
PkgLink:=LazPackageLinks.FindLinkWithDependencyWithIgnore(Dependency,IgnoreFiles);
if PkgLink=nil then break;
Filename:=PkgLink.GetEffectiveFilename;
if ParseLPK(Filename,Version) then begin
@ -5790,7 +5794,7 @@ begin
// nothing found via dependencies
// search in links
PkgLink:=LazPackageLinks.FindLinkWithPkgName(APackage.Name,IgnoreFiles);
PkgLink:=LazPackageLinks.FindLinkWithPkgNameWithIgnore(APackage.Name,IgnoreFiles);
if PkgLink<>nil then begin
Result:=PkgLink.GetEffectiveFilename;
exit;

View File

@ -37,9 +37,16 @@ unit PkgLinksDlg;
interface
uses
Classes, SysUtils, Forms, Controls, StdCtrls,
Buttons, Grids, ExtCtrls, ComCtrls, Menus, AvgLvlTree, LazUTF8,
FileProcs, LazFileUtils, LazFileCache, PackageIntf,
Classes, SysUtils,
// LCL
Forms, Controls, StdCtrls, Buttons, Grids, ExtCtrls, ComCtrls, Menus,
// Codetools
FileProcs,
// LazUtils
AvgLvlTree, LazUTF8, LazFileUtils, LazFileCache,
// IdeIntf
PackageLinkIntf, PackageIntf,
// IDE
LazarusIDEStrConsts, PackageLinks, LPKCache;
type

View File

@ -56,7 +56,7 @@ uses
CodeToolsConfig, CodeToolManager, CodeCache, CodeToolsStructs, BasicCodeTools,
FileProcs, CodeTree,
// IDE Interface
NewItemIntf, ProjPackIntf, ProjectIntf, PackageIntf, PackageDependencyIntf,
NewItemIntf, ProjPackIntf, ProjectIntf, PackageIntf, PackageDependencyIntf, PackageLinkIntf,
CompOptsIntf, MenuIntf, IDEWindowIntf, IDEExternToolIntf, MacroIntf, LazIDEIntf,
IDEMsgIntf, SrcEditorIntf, ComponentReg, PropEdits, IDEDialogs, UnitResources,
// IDE
@ -3247,7 +3247,7 @@ end;
function TPkgManager.AddPackageToGraph(APackage: TLazPackage): TModalResult;
var
ConflictPkg: TLazPackage;
Link: TLazPackageLink;
Link: TPackageLink;
begin
// check Package Name
if not IsValidPkgName(APackage.Name) then begin
@ -3689,7 +3689,7 @@ function TPkgManager.DoSavePackage(APackage: TLazPackage;
Flags: TPkgSaveFlags): TModalResult;
var
XMLConfig: TCodeBufXMLConfig;
PkgLink: TLazPackageLink;
PkgLink: TPackageLink;
Code: TCodeBuffer;
begin
// do not save during compilation
@ -4039,7 +4039,7 @@ var
function ReloadPkg(APackage: TLazPackage): boolean;
var
Link: TLazPackageLink;
Link: TPackageLink;
MsgResult: TModalResult;
Filename: String;
begin