diff --git a/components/codetools/codetoolmanager.pas b/components/codetools/codetoolmanager.pas index be3f9f4dea..475ef9c68b 100644 --- a/components/codetools/codetoolmanager.pas +++ b/components/codetools/codetoolmanager.pas @@ -135,6 +135,9 @@ type IdentifierHistory: TIdentifierHistoryList; Positions: TCodeXYPositions; + constructor Create; + destructor Destroy; override; + procedure ActivateWriteLock; procedure DeactivateWriteLock; @@ -200,6 +203,9 @@ type function GetPPWSrcPathForDirectory(const Directory: string): string; function GetDCUSrcPathForDirectory(const Directory: string): string; function GetCompiledSrcPathForDirectory(const Directory: string): string; + function GetNestedCommentsFlagForFile(const Filename: string): boolean; + function GetPascalCompilerForDirectory(const Directory: string): TPascalCompiler; + function GetCompilerModeForDirectory(const Directory: string): TCompilerMode; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -216,8 +222,9 @@ type var NewCode: TCodeBuffer; var NewX, NewY, NewTopLine: integer): boolean; - // keywords + // keywords and comments function IsKeyword(Code: TCodeBuffer; const KeyWord: string): boolean; + function ExtractCodeWithoutComments(Code: TCodeBuffer): string; // blocks (e.g. begin..end, case..end, try..finally..end, repeat..until) function FindBlockCounterPart(Code: TCodeBuffer; X,Y: integer; @@ -375,9 +382,6 @@ type // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - constructor Create; - destructor Destroy; override; - function ConsistencyCheck: integer; // 0 = ok procedure WriteDebugReport(WriteTool, WriteDefPool, WriteDefTree, WriteCache, WriteGlobalValues: boolean); @@ -633,6 +637,56 @@ begin Result:=DefineTree.GetCompiledSrcPathForDirectory(Directory); end; +function TCodeToolManager.GetNestedCommentsFlagForFile( + const Filename: string): boolean; +var + Evaluator: TExpressionEvaluator; + Directory: String; +begin + Result:=false; + Directory:=ExtractFilePath(Filename); + // check pascal compiler is FPC and mode is FPC or OBJFPC + if GetPascalCompilerForDirectory(Directory)<>pcFPC then exit; + if not (GetCompilerModeForDirectory(Directory) in [cmFPC,cmOBJFPC]) then exit; + // check Nested Compiler define is on + Evaluator:=DefineTree.GetDefinesForDirectory(Directory,true); + if Evaluator=nil then exit; + if ((Evaluator.IsDefined(NestedCompilerDefine)) + or (CompareFileExt(Filename,'pp',false)=0)) + then + Result:=true; +end; + +function TCodeToolManager.GetPascalCompilerForDirectory(const Directory: string + ): TPascalCompiler; +var + Evaluator: TExpressionEvaluator; + PascalCompiler: string; + pc: TPascalCompiler; +begin + Result:=pcFPC; + Evaluator:=DefineTree.GetDefinesForDirectory(Directory,true); + if Evaluator=nil then exit; + PascalCompiler:=Evaluator.Variables[PascalCompilerDefine]; + for pc:=Low(TPascalCompiler) to High(TPascalCompiler) do + if (PascalCompiler=PascalCompilerNames[pc]) then + Result:=pc; +end; + +function TCodeToolManager.GetCompilerModeForDirectory(const Directory: string + ): TCompilerMode; +var + Evaluator: TExpressionEvaluator; + cm: TCompilerMode; +begin + Result:=cmFPC; + Evaluator:=DefineTree.GetDefinesForDirectory(Directory,true); + if Evaluator=nil then exit; + for cm:=Low(TCompilerMode) to High(TCompilerMode) do + if Evaluator.IsDefined(CompilerModeVars[cm]) then + Result:=cm; +end; + function TCodeToolManager.InitCurCodeTool(Code: TCodeBuffer): boolean; var MainCode: TCodeBuffer; begin @@ -1170,6 +1224,12 @@ begin end; end; +function TCodeToolManager.ExtractCodeWithoutComments(Code: TCodeBuffer): string; +begin + Result:=CleanCodeFromComments(Code.Source, + GetNestedCommentsFlagForFile(Code.Filename)); +end; + function TCodeToolManager.FindBlockCounterPart(Code: TCodeBuffer; X, Y: integer; var NewCode: TCodeBuffer; var NewX, NewY, NewTopLine: integer ): boolean; diff --git a/components/codetools/definetemplates.pas b/components/codetools/definetemplates.pas index b3e93362b8..29d0bf6ccc 100644 --- a/components/codetools/definetemplates.pas +++ b/components/codetools/definetemplates.pas @@ -1588,11 +1588,11 @@ begin end; function TDefineTree.GetUnitPathForDirectory(const Directory: string): string; -var ExprEval: TExpressionEvaluator; +var Evaluator: TExpressionEvaluator; begin - ExprEval:=GetDefinesForDirectory(Directory,true); - if ExprEval<>nil then begin - Result:=ExprEval.Variables[UnitPathMacroName]; + Evaluator:=GetDefinesForDirectory(Directory,true); + if Evaluator<>nil then begin + Result:=Evaluator.Variables[UnitPathMacroName]; end else begin Result:=''; end; @@ -1600,22 +1600,22 @@ end; function TDefineTree.GetIncludePathForDirectory(const Directory: string ): string; -var ExprEval: TExpressionEvaluator; +var Evaluator: TExpressionEvaluator; begin - ExprEval:=GetDefinesForDirectory(Directory,true); - if ExprEval<>nil then begin - Result:=ExprEval.Variables[IncludePathMacroName]; + Evaluator:=GetDefinesForDirectory(Directory,true); + if Evaluator<>nil then begin + Result:=Evaluator.Variables[IncludePathMacroName]; end else begin Result:=''; end; end; function TDefineTree.GetSrcPathForDirectory(const Directory: string): string; -var ExprEval: TExpressionEvaluator; +var Evaluator: TExpressionEvaluator; begin - ExprEval:=GetDefinesForDirectory(Directory,true); - if ExprEval<>nil then begin - Result:=ExprEval.Variables[SrcPathMacroName]; + Evaluator:=GetDefinesForDirectory(Directory,true); + if Evaluator<>nil then begin + Result:=Evaluator.Variables[SrcPathMacroName]; end else begin Result:=''; end; @@ -1623,11 +1623,11 @@ end; function TDefineTree.GetPPUSrcPathForDirectory(const Directory: string ): string; -var ExprEval: TExpressionEvaluator; +var Evaluator: TExpressionEvaluator; begin - ExprEval:=GetDefinesForDirectory(Directory,true); - if ExprEval<>nil then begin - Result:=ExprEval.Variables[PPUSrcPathMacroName]; + Evaluator:=GetDefinesForDirectory(Directory,true); + if Evaluator<>nil then begin + Result:=Evaluator.Variables[PPUSrcPathMacroName]; end else begin Result:=''; end; @@ -1635,11 +1635,11 @@ end; function TDefineTree.GetPPWSrcPathForDirectory(const Directory: string ): string; -var ExprEval: TExpressionEvaluator; +var Evaluator: TExpressionEvaluator; begin - ExprEval:=GetDefinesForDirectory(Directory,true); - if ExprEval<>nil then begin - Result:=ExprEval.Variables[PPWSrcPathMacroName]; + Evaluator:=GetDefinesForDirectory(Directory,true); + if Evaluator<>nil then begin + Result:=Evaluator.Variables[PPWSrcPathMacroName]; end else begin Result:=''; end; @@ -1647,11 +1647,11 @@ end; function TDefineTree.GetDCUSrcPathForDirectory(const Directory: string ): string; -var ExprEval: TExpressionEvaluator; +var Evaluator: TExpressionEvaluator; begin - ExprEval:=GetDefinesForDirectory(Directory,true); - if ExprEval<>nil then begin - Result:=ExprEval.Variables[DCUSrcPathMacroName]; + Evaluator:=GetDefinesForDirectory(Directory,true); + if Evaluator<>nil then begin + Result:=Evaluator.Variables[DCUSrcPathMacroName]; end else begin Result:=''; end; @@ -1659,11 +1659,12 @@ end; function TDefineTree.GetCompiledSrcPathForDirectory(const Directory: string ): string; -var ExprEval: TExpressionEvaluator; +var + Evaluator: TExpressionEvaluator; begin - ExprEval:=GetDefinesForDirectory(Directory,true); - if ExprEval<>nil then begin - Result:=ExprEval.Variables[CompiledSrcPathMacroName]; + Evaluator:=GetDefinesForDirectory(Directory,true); + if Evaluator<>nil then begin + Result:=Evaluator.Variables[CompiledSrcPathMacroName]; end else begin Result:=''; end; diff --git a/ide/mainbar.pas b/ide/mainbar.pas index 779c2eadda..ae24532cc9 100644 --- a/ide/mainbar.pas +++ b/ide/mainbar.pas @@ -42,8 +42,8 @@ uses {$ENDIF} Classes, LCLType, LCLLinux, Compiler, StdCtrls, Forms, Buttons, Menus, ComCtrls, Spin, SysUtils, FileCtrl, - Controls, Graphics, ExtCtrls, Dialogs, CodeToolManager, SynEditKeyCmds, - LazConf, LazarusIDEStrConsts, ProjectDefs, Project, + Controls, Graphics, ExtCtrls, Dialogs, CodeToolManager, CodeCache, + SynEditKeyCmds, LazConf, LazarusIDEStrConsts, ProjectDefs, Project, {$IFDEF EnablePkgs} ComponentReg, {$ELSE} @@ -131,7 +131,9 @@ type TLoadBufferFlag = ( lbfUpdateFromDisk, lbfRevert, - lbfCheckIfText + lbfCheckIfText, + lbfQuiet, + lbfCreateClearOnError ); TLoadBufferFlags = set of TLoadBufferFlag; @@ -384,10 +386,6 @@ type function DoInitProjectRun: TModalResult; virtual; abstract; function DoOpenMacroFile(Sender: TObject; const AFilename: string): TModalResult; virtual; - function DoCheckCreatingFile(const AFilename: string; - CheckReadable: boolean): TModalResult; virtual; - function DoSaveStringToFile(const Filename, Src, - FileDescription: string): TModalResult; virtual; abstract; function DoShowProjectInspector: TModalResult; virtual; abstract; @@ -395,7 +393,17 @@ type function DoSaveForBuild: TModalResult; virtual; abstract; function DoCheckFilesOnDisk: TModalResult; virtual; abstract; function DoCheckAmbigiousSources(const AFilename: string; - Compiling: boolean): TModalResult; + Compiling: boolean): TModalResult; virtual; + function DoCheckCreatingFile(const AFilename: string; + CheckReadable: boolean): TModalResult; virtual; + function DoSaveStringToFile(const Filename, Src, + FileDescription: string): TModalResult; virtual; abstract; + function DoLoadCodeBuffer(var ACodeBuffer: TCodeBuffer; + const AFilename: string; + Flags: TLoadBufferFlags): TModalResult; virtual; abstract; + function DoSaveCodeBufferToFile(ABuffer: TCodeBuffer; + const AFilename: string; + IsPartOfProject:boolean): TModalResult; virtual; abstract; function DoBackupFile(const Filename:string; IsPartOfProject:boolean): TModalResult; virtual; abstract; function DoDeleteAmbigiousFiles(const Filename:string diff --git a/packager/addtopackagedlg.pas b/packager/addtopackagedlg.pas index 9de18a3f7f..a327594b84 100644 --- a/packager/addtopackagedlg.pas +++ b/packager/addtopackagedlg.pas @@ -742,7 +742,7 @@ begin if (LazPackage<>ARequiredPackage) and (not LazPackage.Requires(PkgComponent.PkgFile.LazPackage)) then - Params.Dependency:=ARequiredPackage.CreateDependencyForThisPkg; + Params.Dependency:=ARequiredPackage.CreateDependencyForThisPkg(nil); end; ModalResult:=mrOk; diff --git a/packager/basepkgmanager.pas b/packager/basepkgmanager.pas index 1edeea8faf..e1a739a474 100644 --- a/packager/basepkgmanager.pas +++ b/packager/basepkgmanager.pas @@ -54,7 +54,8 @@ type TPkgSaveFlags = set of TPkgSaveFlag; TPkgOpenFlag = ( - pofAddToRecent + pofAddToRecent, + pofRevert ); TPkgOpenFlags = set of TPkgOpenFlag; @@ -125,7 +126,8 @@ const ); PkgOpenFlagNames: array[TPkgOpenFlag] of string = ( - 'pofAddToRecent' + 'pofAddToRecent', + 'pofRevert' ); PkgCompileFlagNames: array[TPkgCompileFlag] of string = ( diff --git a/packager/openinstalledpkgdlg.pas b/packager/openinstalledpkgdlg.pas index d45a5d799a..2b93d8c5c3 100644 --- a/packager/openinstalledpkgdlg.pas +++ b/packager/openinstalledpkgdlg.pas @@ -207,6 +207,8 @@ function TOpenInstalledPackagesDlg.PkgStateToString(APackage: TLazPackage begin Result:=''; + if APackage.Modified then AddState('modified'); + if APackage.Missing then AddState('missing'); case APackage.Installed of pitStatic: AddState('installed static'); pitDynamic: AddState('installed dynamic'); @@ -215,6 +217,7 @@ begin pitStatic: AddState('auto install static'); pitDynamic: AddState('auto install dynamic'); end; + if APackage.ReadOnly then AddState('readonly'); end; constructor TOpenInstalledPackagesDlg.Create(TheOwner: TComponent); diff --git a/packager/packagedefs.pas b/packager/packagedefs.pas index 1eee5edcc6..1d74caaea8 100644 --- a/packager/packagedefs.pas +++ b/packager/packagedefs.pas @@ -347,6 +347,7 @@ type TLazPackageDefineTemplates = class private + FActive: boolean; FFlags: TLazPkgDefineTemplatesFlags; fLastOutputDirSrcPathIDAsString: string; fLastSourceDirectories: TStringList; @@ -357,6 +358,7 @@ type FOutputDir: TDefineTemplate; FOutPutSrcPath: TDefineTemplate; FUpdateLock: integer; + procedure SetActive(const AValue: boolean); procedure UpdateMain; procedure UpdateDefinesForOutputDirectory; procedure UpdateDefinesForSourceDirectories; @@ -375,6 +377,7 @@ type property Main: TDefineTemplate read FMain; property OutputDir: TDefineTemplate read FOutputDir; property OutPutSrcPath: TDefineTemplate read FOutPutSrcPath; + property Active: boolean read FActive write SetActive; end; @@ -529,6 +532,9 @@ type function AddFile(const NewFilename, NewUnitName: string; NewFileType: TPkgFileType; NewFlags: TPkgFileFlags; CompPriorityCat: TComponentPriorityCategory): TPkgFile; + function AddRemovedFile(const NewFilename, NewUnitName: string; + NewFileType: TPkgFileType; NewFlags: TPkgFileFlags; + CompPriorityCat: TComponentPriorityCategory): TPkgFile; procedure RemoveFile(PkgFile: TPkgFile); procedure UnremovePkgFile(PkgFile: TPkgFile); // required dependencies (plus removed required dependencies) @@ -542,7 +548,7 @@ type procedure RemoveRemovedDependency(Dependency: TPkgDependency); procedure MoveRequiredDependencyUp(Dependency: TPkgDependency); procedure MoveRequiredDependencyDown(Dependency: TPkgDependency); - function CreateDependencyForThisPkg: TPkgDependency; + function CreateDependencyForThisPkg(NewOwner: TObject): TPkgDependency; function Requires(APackage: TLazPackage): boolean; procedure GetAllRequiredPackages(var List: TList); // components @@ -618,8 +624,12 @@ type { TBasePackageEditor } TBasePackageEditor = class(TForm) + protected + function GetLazPackage: TLazPackage; virtual; abstract; + procedure SetLazPackage(const AValue: TLazPackage); virtual; abstract; public procedure UpdateAll; virtual; abstract; + property LazPackage: TLazPackage read GetLazPackage write SetLazPackage; end; @@ -2197,6 +2207,26 @@ begin FFiles.Add(Result); end; +function TLazPackage.AddRemovedFile(const NewFilename, NewUnitName: string; + NewFileType: TPkgFileType; NewFlags: TPkgFileFlags; + CompPriorityCat: TComponentPriorityCategory): TPkgFile; +begin + Result:=FindRemovedPkgFile(NewFilename); + if Result=nil then begin + Result:=TPkgFile.Create(Self); + Result.Removed:=false; + end; + with Result do begin + Filename:=NewFilename; + UnitName:=NewUnitName; + FileType:=NewFileType; + Flags:=NewFlags; + ComponentPriority:=ComponentPriorityNormal; + ComponentPriority.Category:=CompPriorityCat; + end; + FRemovedFiles.Add(Result); +end; + procedure TLazPackage.RemoveFile(PkgFile: TPkgFile); begin FFiles.Remove(PkgFile); @@ -2258,10 +2288,12 @@ begin Dependency.MoveDownInList(FFirstRequiredDependency,pdlRequires); end; -function TLazPackage.CreateDependencyForThisPkg: TPkgDependency; +function TLazPackage.CreateDependencyForThisPkg( + NewOwner: TObject): TPkgDependency; begin Result:=TPkgDependency.Create; with Result do begin + Owner:=NewOwner; PackageName:=Self.Name; MinVersion.Assign(Version); Flags:=[pdfMinVersion]; @@ -2784,7 +2816,7 @@ end; procedure TLazPackageDefineTemplates.UpdateMain; begin - if not LazPackage.NeedsDefineTemplates then exit; + if (not LazPackage.NeedsDefineTemplates) or (not Active) then exit; // update the package block define template (the container for all other // define templates of the package) if FMain=nil then begin @@ -2796,9 +2828,16 @@ begin // ClearCache is here unnessary, because it is only a block end; +procedure TLazPackageDefineTemplates.SetActive(const AValue: boolean); +begin + if FActive=AValue then exit; + FActive:=AValue; + if not FActive then Clear else AllChanged; +end; + procedure TLazPackageDefineTemplates.UpdateDefinesForOutputDirectory; begin - if not LazPackage.NeedsDefineTemplates then exit; + if (not LazPackage.NeedsDefineTemplates) or (not Active) then exit; if FMain=nil then UpdateMain; if FOutputDir=nil then begin @@ -2833,7 +2872,7 @@ var IncPathDefTempl: TDefineTemplate; IDHasChanged: Boolean; begin - if not LazPackage.NeedsDefineTemplates then exit; + if (not LazPackage.NeedsDefineTemplates) or (not Active) then exit; // quick check if something has changed IDHasChanged:=fLastSourceDirsIDAsString<>LazPackage.IDAsString; diff --git a/packager/packageeditor.pas b/packager/packageeditor.pas index 72af339142..810272999e 100644 --- a/packager/packageeditor.pas +++ b/packager/packageeditor.pas @@ -51,6 +51,8 @@ type TOnSavePackage = function(Sender: TObject; APackage: TLazPackage; SaveAs: boolean): TModalResult of object; + TOnRevertPackage = + function(Sender: TObject; APackage: TLazPackage): TModalResult of object; TOnCompilePackage = function(Sender: TObject; APackage: TLazPackage; CompileClean, CompileRequired: boolean): TModalResult of object; @@ -133,6 +135,7 @@ type procedure RegisteredListBoxDrawItem(Control: TWinControl; Index: Integer; ARect: TRect; State: TOwnerDrawState); procedure RemoveBitBtnClick(Sender: TObject); + procedure RevertClick(Sender: TObject); procedure SaveBitBtnClick(Sender: TObject); procedure SaveAsClick(Sender: TObject); procedure UninstallClick(Sender: TObject); @@ -145,7 +148,7 @@ type RemovedFilesNode: TTreeNode; RemovedRequiredNode: TTreeNode; FPlugins: TStringList; - procedure SetLazPackage(const AValue: TLazPackage); + procedure SetLazPackage(const AValue: TLazPackage); override; procedure SetupComponents; procedure UpdateAll; override; procedure UpdateTitle; @@ -164,6 +167,7 @@ type destructor Destroy; override; procedure DoSave(SaveAs: boolean); procedure DoCompile(CompileClean, CompileRequired: boolean); + procedure DoRevert; public property LazPackage: TLazPackage read FLazPackage write SetLazPackage; end; @@ -183,6 +187,7 @@ type FOnInstallPackage: TOnInstallPackage; FOnOpenFile: TOnOpenFile; FOnOpenPackage: TOnOpenPackage; + FOnRevertPackage: TOnRevertPackage; FOnSavePackage: TOnSavePackage; FOnUninstallPackage: TOnUninstallPackage; function GetEditors(Index: integer): TPackageEditorForm; @@ -207,6 +212,7 @@ type function CreateNewFile(Sender: TObject; const Params: TAddToPkgResult): TModalResult; function SavePackage(APackage: TLazPackage; SaveAs: boolean): TModalResult; + function RevertPackage(APackage: TLazPackage): TModalResult; function CompilePackage(APackage: TLazPackage; CompileClean,CompileRequired: boolean): TModalResult; procedure UpdateAllEditors; @@ -217,13 +223,18 @@ type property OnCreateNewFile: TOnCreateNewPkgFile read FOnCreateNewFile write FOnCreateNewFile; property OnOpenFile: TOnOpenFile read FOnOpenFile write FOnOpenFile; - property OnOpenPackage: TOnOpenPackage read FOnOpenPackage write FOnOpenPackage; + property OnOpenPackage: TOnOpenPackage read FOnOpenPackage + write FOnOpenPackage; property OnGetIDEFileInfo: TGetIDEFileStateEvent read FOnGetIDEFileInfo write FOnGetIDEFileInfo; property OnGetUnitRegisterInfo: TOnGetUnitRegisterInfo read FOnGetUnitRegisterInfo write FOnGetUnitRegisterInfo; - property OnFreeEditor: TOnFreePkgEditor read FOnFreeEditor write FOnFreeEditor; - property OnSavePackage: TOnSavePackage read FOnSavePackage write FOnSavePackage; + property OnFreeEditor: TOnFreePkgEditor read FOnFreeEditor + write FOnFreeEditor; + property OnSavePackage: TOnSavePackage read FOnSavePackage + write FOnSavePackage; + property OnRevertPackage: TOnRevertPackage read FOnRevertPackage + write FOnRevertPackage; property OnCompilePackage: TOnCompilePackage read FOnCompilePackage write FOnCompilePackage; property OnInstallPackage: TOnInstallPackage read FOnInstallPackage @@ -436,6 +447,7 @@ begin AddPopupMenuItem('Save',@SaveBitBtnClick,SaveBitBtn.Enabled); AddPopupMenuItem('Save As',@SaveAsClick,not LazPackage.AutoCreated); + AddPopupMenuItem('Revert',@RevertClick,not LazPackage.AutoCreated); AddPopupMenuItem('-',nil,true); AddPopupMenuItem('Compile',@CompileBitBtnClick,CompileBitBtn.Enabled); AddPopupMenuItem('Recompile clean',@CompileCleanClick,CompileBitBtn.Enabled); @@ -658,6 +670,11 @@ begin end; end; +procedure TPackageEditorForm.RevertClick(Sender: TObject); +begin + DoRevert; +end; + procedure TPackageEditorForm.SaveBitBtnClick(Sender: TObject); begin DoSave(false); @@ -898,6 +915,9 @@ end; procedure TPackageEditorForm.CompileAllCleanClick(Sender: TObject); begin + if MessageDlg('Compile everything?', + 'Re-Compile this and all required packages?', + mtConfirmation,[mbYes,mbNo],0)<>mrYes then exit; DoCompile(true,true); end; @@ -1568,6 +1588,12 @@ begin UpdateStatusBar; end; +procedure TPackageEditorForm.DoRevert; +begin + PackageEditors.RevertPackage(LazPackage); + UpdateAll; +end; + constructor TPackageEditorForm.Create(TheOwner: TComponent); begin inherited Create(TheOwner); @@ -1849,6 +1875,12 @@ begin Result:=OnUninstallPackage(Self,APackage); end; +function TPackageEditors.RevertPackage(APackage: TLazPackage): TModalResult; +begin + if Assigned(OnRevertPackage) then + Result:=OnRevertPackage(Self,APackage); +end; + { TPackageEditorLayout } constructor TPackageEditorLayout.Create; diff --git a/packager/packagesystem.pas b/packager/packagesystem.pas index 0f458aec95..9f37a4a987 100644 --- a/packager/packagesystem.pas +++ b/packager/packagesystem.pas @@ -373,6 +373,7 @@ begin BeginUpdate(true); CurPkg:=Packages[Index]; CurPkg.Flags:=CurPkg.Flags+[lpfDestroying]; + CurPkg.DefineTemplates.Active:=false; if Assigned(OnDeletePackage) then OnDeletePackage(CurPkg); FItems.Delete(Index); FTree.Remove(CurPkg); @@ -848,7 +849,7 @@ begin CompilerOptions.UnitOutputDirectory:=''; // add requirements - AddRequiredDependency(FCLPackage.CreateDependencyForThisPkg); + AddRequiredDependency(FCLPackage.CreateDependencyForThisPkg(Result)); // add registering units AddFile('menus.pp','Menus',pftUnit,[pffHasRegisterProc],cpBase); @@ -900,7 +901,7 @@ begin CompilerOptions.UnitOutputDirectory:=''; // add requirements - AddRequiredDependency(LCLPackage.CreateDependencyForThisPkg); + AddRequiredDependency(LCLPackage.CreateDependencyForThisPkg(Result)); // add units AddFile('synedit.pp','SynEdit',pftUnit,[],cpBase); @@ -951,8 +952,8 @@ begin UsageOptions.UnitPath:='$(LazarusDir)/components/custom'; // add requirements - AddRequiredDependency(LCLPackage.CreateDependencyForThisPkg); - AddRequiredDependency(SynEditPackage.CreateDependencyForThisPkg); + AddRequiredDependency(LCLPackage.CreateDependencyForThisPkg(Result)); + AddRequiredDependency(SynEditPackage.CreateDependencyForThisPkg(Result)); Modified:=false; end; @@ -975,20 +976,68 @@ begin // update all missing dependencies UpdateBrokenDependenciesToPackage(APackage); + + // activate define templates + APackage.DefineTemplates.Active:=true; if Assigned(OnAddPackage) then OnAddPackage(APackage); EndUpdate; end; procedure TLazPackageGraph.ReplacePackage(OldPackage, NewPackage: TLazPackage); + + procedure MoveInstalledComponents(OldPkgFile: TPkgFile); + var + NewPkgFile: TPkgFile; + OldUnitName: String; + PkgComponent: TPkgComponent; + begin + if (OldPkgFile.ComponentCount>0) then begin + OldUnitName:=OldPkgFile.UnitName; + if OldUnitName='' then RaiseException('MoveInstalledComponents'); + NewPkgFile:=NewPackage.FindUnit(OldUnitName,false); + if NewPkgFile=nil then begin + NewPkgFile:=NewPackage.AddRemovedFile(OldPkgFile.Filename,OldUnitName, + OldPkgFile.FileType,OldPkgFile.Flags, + OldPkgFile.ComponentPriority.Category); + end; + while OldPkgFile.ComponentCount>0 do begin + PkgComponent:=OldPkgFile.Components[0]; + OldPkgFile.RemovePkgComponent(PkgComponent); + NewPkgFile.AddPkgComponent(PkgComponent); + end; + end; + end; + var OldInstalled: TPackageInstallType; + OldAutoInstall: TPackageInstallType; + OldEditor: TBasePackageEditor; + i: Integer; begin BeginUpdate(true); + // save flags OldInstalled:=OldPackage.Installed; + OldAutoInstall:=OldPackage.AutoInstall; + OldEditor:=OldPackage.Editor; + if OldEditor<>nil then begin + OldEditor.LazPackage:=nil; + end; + // migrate components + for i:=0 to OldPackage.FileCount-1 do + MoveInstalledComponents(OldPackage.Files[i]); + for i:=0 to OldPackage.RemovedFilesCount-1 do + MoveInstalledComponents(OldPackage.RemovedFiles[i]); + // delete old package Delete(fItems.IndexOf(OldPackage)); + // restore flags NewPackage.Installed:=OldInstalled; + NewPackage.AutoInstall:=OldAutoInstall; + // add package to graph AddPackage(NewPackage); + if OldEditor<>nil then begin + OldEditor.LazPackage:=NewPackage; + end; EndUpdate; end; @@ -1262,7 +1311,7 @@ function TLazPackageGraph.GetAutoCompilationOrder(APackage: TLazPackage; // The packages will be in topological order, with the package that should be // compiled first at the end. - procedure GetLevelOrder(Dependency: TPkgDependency); + procedure GetTopologicalOrder(Dependency: TPkgDependency); var RequiredPackage: TLazPackage; begin @@ -1273,7 +1322,7 @@ function TLazPackageGraph.GetAutoCompilationOrder(APackage: TLazPackage; RequiredPackage.Flags:=RequiredPackage.Flags+[lpfVisited]; if RequiredPackage.AutoUpdate in Policies then begin // add first all needed packages - GetLevelOrder(RequiredPackage.FirstRequiredDependency); + GetTopologicalOrder(RequiredPackage.FirstRequiredDependency); // then add this package if Result=nil then Result:=TList.Create; Result.Add(RequiredPackage); @@ -1291,7 +1340,7 @@ begin APackage.Flags:=APackage.Flags+[lpfVisited]; FirstDependency:=APackage.FirstRequiredDependency; end; - GetLevelOrder(FirstDependency); + GetTopologicalOrder(FirstDependency); end; procedure TLazPackageGraph.MarkAllPackagesAsNotVisited; @@ -1409,43 +1458,10 @@ end; function TLazPackageGraph.PackageCanBeReplaced( OldPackage, NewPackage: TLazPackage): boolean; -var - Dependency: TPkgDependency; begin - Result:=false; - if OldPackage.Missing and (AnsiCompareText(OldPackage.Name,NewPackage.Name)=0) - then begin - Result:=true; - exit; - end; + if AnsiCompareText(OldPackage.Name,NewPackage.Name)<>0 then + RaiseException('TLazPackageGraph.PackageCanBeReplaced'); - if PackageIsNeeded(OldPackage) then exit; - - // check all used-by dependencies - Dependency:=OldPackage.FirstUsedByDependency; - if Dependency<>nil then begin - MarkNeededPackages; - while Dependency<>nil do begin - if (not Dependency.IsCompatible(NewPackage)) then begin - // replacing will break this dependency - // -> check if Owner is needed - if (Dependency.Owner=nil) then begin - // dependency has no owner -> can be broken - end else if (Dependency.Owner is TLazPackage) then begin - if lpfNeeded in TLazPackage(Dependency.Owner).Flags then begin - // a needed package needs old package -> can no be broken - exit; - end else begin - // an unneeded package needs old package -> can be broken - end; - end else begin - // an other thing (e.g. a project) needs old package -> can not be broken - exit; - end; - end; - Dependency:=Dependency.NextUsedByDependency; - end; - end; Result:=true; end; diff --git a/packager/pkgmanager.pas b/packager/pkgmanager.pas index 45de511fd0..502432493b 100644 --- a/packager/pkgmanager.pas +++ b/packager/pkgmanager.pas @@ -45,14 +45,14 @@ uses MemCheck, {$ENDIF} Classes, SysUtils, LCLProc, Forms, Controls, FileCtrl, - Dialogs, Menus, CodeToolManager, CodeCache, Laz_XMLCfg, AVL_Tree, - LazarusIDEStrConsts, KeyMapping, EnvironmentOpts, MiscOptions, IDEProcs, - ProjectDefs, InputHistory, IDEDefs, Project, ComponentReg, UComponentManMain, - PackageEditor, AddToPackageDlg, PackageDefs, PackageLinks, PackageSystem, - OpenInstalledPkgDlg, PkgGraphExplorer, BrokenDependenciesDlg, CompilerOptions, - ExtToolDialog, ExtToolEditDlg, EditDefineTree, DefineTemplates, LazConf, - ProjectInspector, ComponentPalette, UnitEditor, AddFileToAPackageDlg, - LazarusPackageIntf, + Dialogs, Menus, CodeToolManager, CodeCache, BasicCodeTools, Laz_XMLCfg, + AVL_Tree, LazarusIDEStrConsts, KeyMapping, EnvironmentOpts, MiscOptions, + IDEProcs, ProjectDefs, InputHistory, IDEDefs, Project, ComponentReg, + UComponentManMain, PackageEditor, AddToPackageDlg, PackageDefs, PackageLinks, + PackageSystem, OpenInstalledPkgDlg, PkgGraphExplorer, BrokenDependenciesDlg, + CompilerOptions, ExtToolDialog, ExtToolEditDlg, EditDefineTree, + DefineTemplates, LazConf, ProjectInspector, ComponentPalette, UnitEditor, + AddFileToAPackageDlg, LazarusPackageIntf, BasePkgManager, MainBar; type @@ -65,6 +65,8 @@ type const Params: TAddToPkgResult): TModalResult; function OnPackageEditorInstallPackage(Sender: TObject; APackage: TLazPackage): TModalResult; + function OnPackageEditorRevertPackage(Sender: TObject; APackage: TLazPackage + ): TModalResult; function OnPackageEditorUninstallPackage(Sender: TObject; APackage: TLazPackage): TModalResult; function OnPackageEditorOpenPackage(Sender: TObject; APackage: TLazPackage @@ -141,7 +143,7 @@ type procedure UnloadInstalledPackages; procedure UpdateVisibleComponentPalette; override; - function AddPackageToGraph(APackage: TLazPackage): TModalResult; + function AddPackageToGraph(APackage: TLazPackage; Replace: boolean): TModalResult; function OpenProjectDependencies(AProject: TProject): TModalResult; override; procedure AddDefaultDependencies(AProject: TProject); override; procedure AddProjectDependency(AProject: TProject; APackage: TLazPackage); override; @@ -324,6 +326,14 @@ begin Result:=DoInstallPackage(APackage); end; +function TPkgManager.OnPackageEditorRevertPackage(Sender: TObject; + APackage: TLazPackage): TModalResult; +begin + if APackage.AutoCreated or (not FilenameIsAbsolute(APackage.Filename)) then + exit; + Result:=DoOpenPackageFile(APackage.Filename,[pofRevert]); +end; + function TPkgManager.OnPackageEditorUninstallPackage(Sender: TObject; APackage: TLazPackage): TModalResult; begin @@ -1065,13 +1075,15 @@ begin sl:=TStringList.Create; Dependency:=FirstAutoInstallDependency; while Dependency<>nil do begin - if (Dependency.LoadPackageResult<>lprSuccess) - or (Dependency.RequiredPackage.AutoCreated) then continue; - sl.Add(Dependency.PackageName); -writeln('TPkgManager.SaveAutoInstallDependencies A ',Dependency.PackageName); + if (Dependency.LoadPackageResult=lprSuccess) + and (not Dependency.RequiredPackage.AutoCreated) then begin + sl.Add(Dependency.PackageName); + writeln('TPkgManager.SaveAutoInstallDependencies A ',Dependency.PackageName); + end; Dependency:=Dependency.NextRequiresDependency; end; MiscellaneousOptions.BuildLazOpts.StaticAutoInstallPackages.Assign(sl); + MiscellaneousOptions.Save; sl.Free; end; @@ -1087,8 +1099,7 @@ begin // add them to auto install list for i:=0 to PackageGraph.LazarusBasePackages.Count-1 do begin BasePackage:=TLazPackage(PackageGraph.LazarusBasePackages[i]); - Dependency:=BasePackage.CreateDependencyForThisPkg; - Dependency.Owner:=Self; + Dependency:=BasePackage.CreateDependencyForThisPkg(Self); PackageGraph.OpenDependency(Dependency); Dependency.AddToList(FirstAutoInstallDependency,pdlRequires); end; @@ -1208,6 +1219,7 @@ begin PackageEditors.OnGetUnitRegisterInfo:=@OnPackageEditorGetUnitRegisterInfo; PackageEditors.OnFreeEditor:=@OnPackageEditorFreeEditor; PackageEditors.OnSavePackage:=@OnPackageEditorSavePackage; + PackageEditors.OnRevertPackage:=@OnPackageEditorRevertPackage; PackageEditors.OnCompilePackage:=@OnPackageEditorCompilePackage; PackageEditors.OnInstallPackage:=@OnPackageEditorInstallPackage; PackageEditors.OnUninstallPackage:=@OnPackageEditorUninstallPackage; @@ -1322,8 +1334,8 @@ begin {$ENDIF} end; -function TPkgManager.AddPackageToGraph(APackage: TLazPackage - ): TModalResult; +function TPkgManager.AddPackageToGraph(APackage: TLazPackage; + Replace: boolean): TModalResult; var ConflictPkg: TLazPackage; begin @@ -1410,7 +1422,7 @@ begin then exit; // add a dependency for the package to the project - NewDependency:=APackage.CreateDependencyForThisPkg; + NewDependency:=APackage.CreateDependencyForThisPkg(AProject); AProject.AddRequiredDependency(NewDependency); PackageGraph.OpenDependency(NewDependency); end; @@ -1447,7 +1459,7 @@ begin // create a new package with standard dependencies NewPackage:=PackageGraph.CreateNewPackage('NewPackage'); PackageGraph.AddDependencyToPackage(NewPackage, - PackageGraph.FCLPackage.CreateDependencyForThisPkg); + PackageGraph.FCLPackage.CreateDependencyForThisPkg(NewPackage)); NewPackage.Modified:=false; // open a package editor @@ -1516,7 +1528,7 @@ begin // check if package is already loaded APackage:=PackageGraph.FindPackageWithFilename(AFilename,true); - if APackage=nil then begin + if (APackage=nil) or (pofRevert in Flags) then begin // package not yet loaded if not FileExists(AFilename) then begin @@ -1567,7 +1579,7 @@ begin end; // integrate it into the graph - Result:=AddPackageToGraph(APackage); + Result:=AddPackageToGraph(APackage,pofRevert in Flags); finally if Result<>mrOk then APackage.Free; end; @@ -1859,6 +1871,7 @@ var RegistrationCode: String; HeaderSrc: String; OutputDir: String; + OldSrc: String; begin writeln('TPkgManager.DoSavePackageMainSource A'); // check if package is ready for saving @@ -1950,6 +1963,15 @@ begin BeautifyStatement(Src,0); Src:=HeaderSrc+Src; + // check if old code is already uptodate + MainIDE.DoLoadCodeBuffer(CodeBuffer,SrcFilename,[lbfQuiet,lbfCheckIfText, + lbfUpdateFromDisk,lbfCreateClearOnError]); + OldSrc:=CodeToolBoss.ExtractCodeWithoutComments(CodeBuffer); + if CompareTextIgnoringSpace(OldSrc,Src,true)=0 then begin + Result:=mrOk; + exit; + end; + // save source Result:=MainIDE.DoSaveStringToFile(SrcFilename,Src,'package main source file'); if Result<>mrOk then exit; @@ -2052,7 +2074,7 @@ var NeedSaving: Boolean; RequiredPackage: TLazPackage; begin - PackageGraph.BeginUpdate(false); + PackageGraph.BeginUpdate(true); PkgList:=nil; try // check if package is designtime package @@ -2104,7 +2126,7 @@ begin RequiredPackage:=TLazPackage(PkgList[i]); if RequiredPackage.AutoInstall=pitNope then begin RequiredPackage.AutoInstall:=pitStatic; - Dependency:=RequiredPackage.CreateDependencyForThisPkg; + Dependency:=RequiredPackage.CreateDependencyForThisPkg(Self); Dependency.AddToList(FirstAutoInstallDependency,pdlRequires); PackageGraph.OpenDependency(Dependency); NeedSaving:=true; @@ -2158,7 +2180,7 @@ begin exit; end; - PackageGraph.BeginUpdate(false); + PackageGraph.BeginUpdate(true); try // save package if APackage.IsVirtual or APackage.Modified then begin