From c7db1f5a24ac06c7a5f39d3ec3baa869bcad7da4 Mon Sep 17 00:00:00 2001 From: mattias Date: Mon, 17 Jan 2011 14:11:35 +0000 Subject: [PATCH] IDE: allow adding multiple units with the same unit name to packages git-svn-id: trunk@29068 - --- packager/addfiletoapackagedlg.pas | 28 ++++++-- packager/addtopackagedlg.pas | 112 +++++++++++++++++------------- packager/packageeditor.pas | 69 ++++++------------ packager/packagesystem.pas | 86 +++++++++++++---------- packager/pkgmanager.pas | 5 +- 5 files changed, 158 insertions(+), 142 deletions(-) diff --git a/packager/addfiletoapackagedlg.pas b/packager/addfiletoapackagedlg.pas index 9de2f900e4..1ee5a1817f 100644 --- a/packager/addfiletoapackagedlg.pas +++ b/packager/addfiletoapackagedlg.pas @@ -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; diff --git a/packager/addtopackagedlg.pas b/packager/addtopackagedlg.pas index 141f8d3930..477b556cf1 100644 --- a/packager/addtopackagedlg.pas +++ b/packager/addtopackagedlg.pas @@ -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; diff --git a/packager/packageeditor.pas b/packager/packageeditor.pas index c93cd25ea0..8c93567429 100644 --- a/packager/packageeditor.pas +++ b/packager/packageeditor.pas @@ -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; diff --git a/packager/packagesystem.pas b/packager/packagesystem.pas index e5aa2ae0f2..1c819960ed 100644 --- a/packager/packagesystem.pas +++ b/packager/packagesystem.pas @@ -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 diff --git a/packager/pkgmanager.pas b/packager/pkgmanager.pas index 7aeafcc694..d5120cec0a 100644 --- a/packager/pkgmanager.pas +++ b/packager/pkgmanager.pas @@ -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;