IDE: allow adding multiple units with the same unit name to packages

git-svn-id: trunk@29068 -
This commit is contained in:
mattias 2011-01-17 14:11:35 +00:00
parent 5efeb35240
commit c7db1f5a24
5 changed files with 158 additions and 142 deletions

View File

@ -42,8 +42,8 @@ uses
Classes, SysUtils, Forms, Controls, Buttons, ExtCtrls, StdCtrls,
Dialogs, AVL_Tree, FileUtil, ButtonPanel,
IDEWindowIntf, PackageIntf,
LazarusIDEStrConsts, IDEProcs,
ComponentReg, PackageDefs, PackageSystem, IDEContextHelpEdit;
IDEDefs, LazarusIDEStrConsts, IDEProcs,
AddToPackageDlg, ComponentReg, PackageDefs, PackageSystem, IDEContextHelpEdit;
type
@ -67,6 +67,7 @@ type
procedure PackagesGroupBoxResize(Sender: TObject);
procedure ShowAllCheckBoxClick(Sender: TObject);
private
FOnGetIDEFileInfo: TGetIDEFileStateEvent;
fPackages: TAVLTree;// tree of TLazPackage
function GetFileType: TPkgFileType;
function GetFilename: string;
@ -85,11 +86,12 @@ type
property Unit_Name: string read GetUnitName write SetUnitName;
property FileType: TPkgFileType read GetFileType write SetFileType;
property HasRegisterProc: boolean read GetHasRegisterProc write SetHasRegisterProc;
property OnGetIDEFileInfo: TGetIDEFileStateEvent read FOnGetIDEFileInfo write FOnGetIDEFileInfo;
end;
function ShowAddFileToAPackageDlg(const Filename, AUnitName: string;
HasRegisterProc: boolean): TModalResult;
HasRegisterProc: boolean; OnGetIDEFileInfo: TGetIDEFileStateEvent): TModalResult;
implementation
@ -97,7 +99,7 @@ implementation
{$R *.lfm}
function ShowAddFileToAPackageDlg(const Filename, AUnitName: string;
HasRegisterProc: boolean): TModalResult;
HasRegisterProc: boolean; OnGetIDEFileInfo: TGetIDEFileStateEvent): TModalResult;
var
AddFileToAPackageDialog: TAddFileToAPackageDialog;
begin
@ -105,6 +107,7 @@ begin
AddFileToAPackageDialog.Filename:=Filename;
AddFileToAPackageDialog.Unit_Name:=AUnitName;
AddFileToAPackageDialog.HasRegisterProc:=HasRegisterProc;
AddFileToAPackageDialog.OnGetIDEFileInfo:=OnGetIDEFileInfo;
AddFileToAPackageDialog.UpdateAvailablePackages;
Result:=AddFileToAPackageDialog.ShowModal;
AddFileToAPackageDialog.Free;
@ -129,7 +132,10 @@ var
APackage: TLazPackage;
PkgFile: TPkgFile;
FileFlags: TPkgFileFlags;
AddType: TAddToPkgType;
aFilename: String;
begin
aFilename:=Filename;
PkgID:=TLazPackageID.Create;
try
// check package ID
@ -157,15 +163,23 @@ begin
end;
// check if file is already in the package
PkgFile:=APackage.FindPkgFile(Filename,true,false);
PkgFile:=APackage.FindPkgFile(aFilename,true,false);
if PkgFile<>nil then begin
MessageDlg(lisPkgMangFileIsAlreadyInPackage,
Format(lisAF2PTheFileIsAlreadyInThePackage, ['"', Filename, '"', #13,
Format(lisAF2PTheFileIsAlreadyInThePackage, ['"', aFilename, '"', #13,
APackage.IDAsString]),
mtError,[mbCancel],0);
exit;
end;
// check filename
if FilenameIsPascalSource(aFilename) then
AddType:=d2ptUnit
else
AddType:=d2ptFile;
if not CheckAddingUnitFilename(APackage,AddType,
OnGetIDEFileInfo,aFilename) then exit;
// ok -> add file to package
APackage.BeginUpdate;
FileFlags:=[];
@ -173,7 +187,7 @@ begin
Include(FileFlags,pffAddToPkgUsesSection);
if HasRegisterProc then
Include(FileFlags,pffHasRegisterProc);
APackage.AddFile(Filename,Unit_Name,FileType,FileFlags,cpNormal);
APackage.AddFile(aFilename,Unit_Name,FileType,FileFlags,cpNormal);
if APackage.Editor<>nil then APackage.Editor.UpdateAll(true);
APackage.EndUpdate;

View File

@ -246,6 +246,14 @@ var
begin
Result:=false;
// check if package is readonly
if LazPackage.ReadOnly then begin
MessageDlg(lisAF2PPackageIsReadOnly,
Format(lisAF2PThePackageIsReadOnly, [LazPackage.IDAsString]),
mtError,[mbCancel],0);
exit;
end;
// normalize filename
AFilename:=TrimFilename(AFilename);
if (AddFileType<>d2ptVirtualUnit) and (not FilenameIsAbsolute(AFilename)) then
@ -273,56 +281,6 @@ begin
end;
end;
// check file extension
if AddFileType in [d2ptUnit,d2ptNewComponent,d2ptVirtualUnit] then begin
if not FilenameIsPascalUnit(AFilename) then begin
MessageDlg(lisA2PFileNotUnit,
lisA2PPascalUnitsMustHaveTheExtensionPPOrPas,
mtWarning,[mbCancel],0);
exit;
end;
end;
// check unitname
if AddFileType in [d2ptUnit,d2ptNewComponent,d2ptVirtualUnit] then begin
AnUnitName:=ExtractFileNameOnly(AFilename);
if not IsValidIdent(AnUnitName) then begin
MessageDlg(lisA2PFileNotUnit,
Format(lisA2PisNotAValidUnitName, ['"', AnUnitName, '"']),
mtWarning,[mbCancel],0);
exit;
end;
// check if unitname already exists in package
PkgFile:=PackageGraph.FindUnit(LazPackage,AnUnitName,true,true);
if PkgFile<>nil then begin
if PkgFile.LazPackage=LazPackage then begin
MessageDlg(lisA2PUnitnameAlreadyExists,
Format(lisA2PTheUnitnameAlreadyExistsInThisPackage, ['"', AnUnitName,
'"']),
mtError,[mbCancel],0);
exit;
end else begin
if MessageDlg(lisA2PUnitnameAlreadyExists,
Format(lisA2PTheUnitnameAlreadyExistsInThePackage, ['"', AnUnitName,
'"', #13, PkgFile.LazPackage.IDAsString]),
mtWarning,[mbCancel,mbIgnore],0)<>mrIgnore then exit;
end;
end;
// check if unitname is a componentclass
if IDEComponentPalette.FindComponent(AnUnitName)<>nil then begin
if MessageDlg(lisA2PAmbiguousUnitName,
Format(lisA2PTheUnitNameIsTheSameAsAnRegisteredComponent, ['"',
AnUnitName, '"', #13]),
mtWarning,[mbCancel,mbIgnore],0)<>mrIgnore
then
exit;
end;
end else begin
AnUnitName:='';
end;
// check if file already exists in package
if FilenameIsAbsolute(AFilename) then begin
PkgFile:=LazPackage.FindPkgFile(AFilename,true,false);
@ -351,6 +309,60 @@ begin
end;
end;
// check file extension
if AddFileType in [d2ptUnit,d2ptNewComponent,d2ptVirtualUnit] then begin
if not FilenameIsPascalUnit(AFilename) then begin
MessageDlg(lisA2PFileNotUnit,
lisA2PPascalUnitsMustHaveTheExtensionPPOrPas,
mtWarning,[mbCancel],0);
exit;
end;
end;
// check unitname
if AddFileType in [d2ptUnit,d2ptNewComponent,d2ptVirtualUnit] then begin
AnUnitName:=ExtractFileNameOnly(AFilename);
if not IsValidIdent(AnUnitName) then begin
MessageDlg(lisA2PFileNotUnit,
Format(lisA2PisNotAValidUnitName, ['"', AnUnitName, '"']),
mtWarning,[mbCancel],0);
exit;
end;
// check if unitname already exists in package
PkgFile:=LazPackage.FindUnit(AnUnitName,true,PkgFile);
if PkgFile<>nil then begin
// a unit with this name already exists in the package
// => warn
if MessageDlg(lisA2PUnitnameAlreadyExists,
Format(lisA2PTheUnitnameAlreadyExistsInThisPackage, ['"', AnUnitName,
'"']),
mtError,[mbCancel,mbIgnore],0)<>mrIgnore then exit;
end else begin
PkgFile:=PackageGraph.FindUnit(LazPackage,AnUnitName,true,true);
if (PkgFile<>nil) and (PkgFile.LazPackage<>LazPackage) then begin
// there is already a unit with this name in another package
// => warn
if MessageDlg(lisA2PUnitnameAlreadyExists,
Format(lisA2PTheUnitnameAlreadyExistsInThePackage, ['"', AnUnitName,
'"', #13, PkgFile.LazPackage.IDAsString]),
mtWarning,[mbCancel,mbIgnore],0)<>mrIgnore then exit;
end;
end;
// check if unitname is a componentclass
if IDEComponentPalette.FindComponent(AnUnitName)<>nil then begin
if MessageDlg(lisA2PAmbiguousUnitName,
Format(lisA2PTheUnitNameIsTheSameAsAnRegisteredComponent, ['"',
AnUnitName, '"', #13]),
mtWarning,[mbCancel,mbIgnore],0)<>mrIgnore
then
exit;
end;
end else begin
AnUnitName:='';
end;
// ok
Result:=true;
end;

View File

@ -1060,47 +1060,7 @@ begin
end;
procedure TPackageEditorForm.FilePropsGroupBoxResize(Sender: TObject);
var
y: Integer;
x: Integer;
w: Integer;
begin
// components for files
w:=(ClientWidth-15) div 2;
with CallRegisterProcCheckBox do
SetBounds(3,0,w,Height);
x:=3+w+9;
with AddToUsesPkgSectionCheckBox do
SetBounds(x,0,w,Height);
y:=CallRegisterProcCheckBox.Top+CallRegisterProcCheckBox.Height+3;
with RegisteredPluginsGroupBox do
SetBounds(0,y,Parent.ClientWidth,Parent.ClientHeight-y);
// components for dependencies
x:=5;
y:=3;
with UseMinVersionCheckBox do
SetBounds(x,y,150,MinVersionEdit.Height);
inc(x,UseMinVersionCheckBox.Width+5);
with MinVersionEdit do
SetBounds(x,y,120,Height);
x:=5;
inc(y,MinVersionEdit.Height+5);
with UseMaxVersionCheckBox do
SetBounds(x,y,UseMinVersionCheckBox.Width,MaxVersionEdit.Height);
inc(x,UseMaxVersionCheckBox.Width+5);
with MaxVersionEdit do
SetBounds(x,y,MinVersionEdit.Width,Height);
inc(y,MaxVersionEdit.Height+10);
x:=5;
with ApplyDependencyButton do
SetBounds(x,y,150,Height);
end;
procedure TPackageEditorForm.AddBitBtnClick(Sender: TObject);
@ -1136,7 +1096,7 @@ procedure TPackageEditorForm.AddBitBtnClick(Sender: TObject);
FNextSelectedPart := LazPackage.AddFile(UnitFilename,Unit_Name,
FileType,PkgFileFlags,cpNormal);
PackageEditors.DeleteAmbiguousFiles(LazPackage,AddParams.UnitFilename);
UpdateAll(true);
UpdateAll(false);
end;
procedure AddVirtualUnit(AddParams: TAddToPkgResult);
@ -1145,7 +1105,7 @@ procedure TPackageEditorForm.AddBitBtnClick(Sender: TObject);
FNextSelectedPart := LazPackage.AddFile(UnitFilename,Unit_Name,FileType,
PkgFileFlags,cpNormal);
PackageEditors.DeleteAmbiguousFiles(LazPackage,AddParams.UnitFilename);
UpdateAll(true);
UpdateAll(false);
end;
procedure AddNewComponent(AddParams: TAddToPkgResult);
@ -1159,9 +1119,10 @@ procedure TPackageEditorForm.AddBitBtnClick(Sender: TObject);
if AddParams.Dependency<>nil then begin
PackageGraph.AddDependencyToPackage(LazPackage,AddParams.Dependency);
end;
PackageEditors.DeleteAmbiguousFiles(LazPackage,AddParams.UnitFilename);
// open file in editor
PackageEditors.CreateNewFile(Self,AddParams);
UpdateAll(true);
UpdateAll(false);
end;
procedure AddRequiredPkg(AddParams: TAddToPkgResult);
@ -1169,6 +1130,7 @@ procedure TPackageEditorForm.AddBitBtnClick(Sender: TObject);
// add dependency
PackageGraph.AddDependencyToPackage(LazPackage,AddParams.Dependency);
FNextSelectedPart := AddParams.Dependency;
UpdateAll(false);
end;
procedure AddFile(AddParams: TAddToPkgResult);
@ -1177,7 +1139,7 @@ procedure TPackageEditorForm.AddBitBtnClick(Sender: TObject);
with AddParams do
FNextSelectedPart := LazPackage.AddFile(UnitFilename,Unit_Name,FileType,
PkgFileFlags,cpNormal);
UpdateAll(true);
UpdateAll(false);
end;
procedure AddNewFile(AddParams: TAddToPkgResult);
@ -1273,13 +1235,26 @@ procedure TPackageEditorForm.AddToUsesPkgSectionCheckBoxChange(Sender: TObject);
var
CurFile: TPkgFile;
Removed: boolean;
i: Integer;
OtherFile: TPkgFile;
begin
if LazPackage=nil then exit;
CurFile:=GetCurrentFile(Removed);
if (CurFile=nil) then exit;
if CurFile.AddToUsesPkgSection=AddToUsesPkgSectionCheckBox.Checked then exit;
CurFile.AddToUsesPkgSection:=AddToUsesPkgSectionCheckBox.Checked;
LazPackage.Modified:=not Removed;
if not Removed then begin
if CurFile.AddToUsesPkgSection then begin
// mark all other units with the same name as unused
for i:=0 to LazPackage.FileCount-1 do begin
OtherFile:=LazPackage.Files[i];
if (OtherFile<>CurFile)
and (SysUtils.CompareText(OtherFile.Unit_Name,CurFile.Unit_Name)=0) then
OtherFile.AddToUsesPkgSection:=false;
end;
end;
LazPackage.Modified:=true;
end;
UpdateAll(true);
end;
@ -1346,7 +1321,9 @@ begin
if (CurFile=nil) then exit;
if CurFile.HasRegisterProc=CallRegisterProcCheckBox.Checked then exit;
CurFile.HasRegisterProc:=CallRegisterProcCheckBox.Checked;
LazPackage.Modified:=not Removed;
if not Removed then begin
LazPackage.Modified:=true;
end;
UpdateAll(true);
end;

View File

@ -49,7 +49,7 @@ uses
Classes, SysUtils, FileProcs, FileUtil, LCLProc, Forms, Controls, Dialogs,
// codetools
AVL_Tree, Laz_XMLCfg, DefineTemplates, CodeCache, BasicCodeTools,
NonPascalCodeTools, SourceChanger, CodeToolManager,
CodeToolsStructs, NonPascalCodeTools, SourceChanger, CodeToolManager,
// IDEIntf,
SrcEditorIntf, IDEExternToolIntf, IDEDialogs, IDEMsgIntf, PackageIntf,
LazIDEIntf,
@ -4037,6 +4037,7 @@ var
CurSrcUnitName: String;
NewShortenSrc: String;
BeautifyCodeOptions: TBeautifyCodeOptions;
AddedUnitNames: TStringToStringTree;
begin
{$IFDEF VerbosePkgCompile}
debugln('TLazPackageGraph.SavePackageMainSource A');
@ -4054,41 +4055,52 @@ begin
e:=LineEnding;
UsedUnits:='';
RegistrationCode:='';
for i:=0 to APackage.FileCount-1 do begin
CurFile:=APackage.Files[i];
if CurFile.FileType=pftMainUnit then continue;
// update unitname
if FilenameIsPascalUnit(CurFile.Filename)
and (CurFile.FileType in PkgFileUnitTypes) then begin
NeedsRegisterProcCall:=CurFile.HasRegisterProc
and (APackage.PackageType in [lptDesignTime,lptRunAndDesignTime]);
if not (NeedsRegisterProcCall or CurFile.AddToUsesPkgSection) then
continue;
AddedUnitNames:=TStringToStringTree.Create(false);
try
for i:=0 to APackage.FileCount-1 do begin
CurFile:=APackage.Files[i];
if CurFile.FileType=pftMainUnit then continue;
// update unitname
if FilenameIsPascalUnit(CurFile.Filename)
and (CurFile.FileType in PkgFileUnitTypes) then begin
NeedsRegisterProcCall:=CurFile.HasRegisterProc
and (APackage.PackageType in [lptDesignTime,lptRunAndDesignTime]);
CurUnitName:=ExtractFileNameOnly(CurFile.Filename);
CurUnitName:=ExtractFileNameOnly(CurFile.Filename);
if CurUnitName=lowercase(CurUnitName) then begin
// the filename is all lowercase, so we can use the nicer unitname from
// the source.
if not (NeedsRegisterProcCall or CurFile.AddToUsesPkgSection) then
continue;
CodeBuffer:=CodeToolBoss.LoadFile(CurFile.Filename,false,false);
if CodeBuffer<>nil then begin
// if the unit is edited, the unitname is probably already cached
CurSrcUnitName:=CodeToolBoss.GetCachedSourceName(CodeBuffer);
// if not then parse it
if SysUtils.CompareText(CurSrcUnitName,CurUnitName)<>0 then
CurSrcUnitName:=CodeToolBoss.GetSourceName(CodeBuffer,false);
// if it makes sense, update unitname
if SysUtils.CompareText(CurSrcUnitName,CurFile.Unit_Name)=0 then
CurFile.Unit_Name:=CurSrcUnitName;
if CurUnitName=lowercase(CurUnitName) then begin
// the filename is all lowercase, so we can use the nicer unitname from
// the source.
CodeBuffer:=CodeToolBoss.LoadFile(CurFile.Filename,false,false);
if CodeBuffer<>nil then begin
// if the unit is edited, the unitname is probably already cached
CurSrcUnitName:=CodeToolBoss.GetCachedSourceName(CodeBuffer);
// if not then parse it
if SysUtils.CompareText(CurSrcUnitName,CurUnitName)<>0 then
CurSrcUnitName:=CodeToolBoss.GetSourceName(CodeBuffer,false);
// if it makes sense, update unitname
if SysUtils.CompareText(CurSrcUnitName,CurFile.Unit_Name)=0 then
CurFile.Unit_Name:=CurSrcUnitName;
end;
if SysUtils.CompareText(CurUnitName,CurFile.Unit_Name)=0 then
CurUnitName:=CurFile.Unit_Name
else
CurFile.Unit_Name:=CurUnitName;
end;
if SysUtils.CompareText(CurUnitName,CurFile.Unit_Name)=0 then
CurUnitName:=CurFile.Unit_Name
else
CurFile.Unit_Name:=CurUnitName;
end;
if (CurUnitName<>'') and IsValidIdent(CurUnitName) then begin
if (CurUnitName='') or (not IsValidIdent(CurUnitName)) then begin
AddMessage(Format(lisIDEInfoWARNINGUnitNameInvalidPackage, [CurFile.
Filename, APackage.IDAsString]),
APackage.Directory);
continue;
end;
if AddedUnitNames.Contains(CurUnitName) then continue;
AddedUnitNames.Add(CurUnitName,'');
if UsedUnits<>'' then
UsedUnits:=UsedUnits+', ';
UsedUnits:=UsedUnits+CurUnitName;
@ -4096,12 +4108,11 @@ begin
RegistrationCode:=RegistrationCode+
' RegisterUnit('''+CurUnitName+''',@'+CurUnitName+'.Register);'+e;
end;
end else begin
AddMessage(Format(lisIDEInfoWARNINGUnitNameInvalidPackage, [CurFile.
Filename, APackage.IDAsString]),
APackage.Directory);
end;
end;
finally
AddedUnitNames.Free;
end;
// append registration code only for design time packages
if (APackage.PackageType in [lptDesignTime,lptRunAndDesignTime]) then begin
@ -4136,8 +4147,9 @@ begin
Src:=HeaderSrc+Src;
if UsedUnits<>'' then
Src:=Src
+BreakString('uses'+e+GetIndentStr(BeautifyCodeOptions.Indent)+UsedUnits+';',
BeautifyCodeOptions.LineLength,BeautifyCodeOptions.Indent)+e
+'uses'+e
+BreakString(GetIndentStr(BeautifyCodeOptions.Indent)+UsedUnits+';',
BeautifyCodeOptions.LineLength,BeautifyCodeOptions.Indent)+e
+e;
Src:=Src+BeautifyCodeOptions.BeautifyStatement(
'implementation'+e

View File

@ -3357,7 +3357,8 @@ begin
end;
end;
Result:=ShowAddFileToAPackageDlg(Filename,TheUnitName,HasRegisterProc);
Result:=ShowAddFileToAPackageDlg(Filename,TheUnitName,HasRegisterProc,
@MainIDE.GetIDEFileState);
end;
function TPkgManager.WarnAboutMissingPackageFiles(APackage: TLazPackage
@ -3371,7 +3372,7 @@ begin
for i:=0 to APackage.FileCount-1 do begin
AFile:=APackage.Files[i];
if AFile.FileType=pftVirtualUnit then continue;
AFilename:=AFile.Filename;
AFilename:=AFile.GetFullFilename;
if System.Pos('$(',AFilename)>0 then begin
// filename contains macros -> skip
end;