diff --git a/ide/compileroptions.pp b/ide/compileroptions.pp index 13b18a5f36..8bbd2fe610 100644 --- a/ide/compileroptions.pp +++ b/ide/compileroptions.pp @@ -136,7 +136,7 @@ type procedure LoadFromXMLConfig(XMLConfig: TXMLConfig; const Path: string; DoSwitchPathDelims: boolean); procedure SaveToXMLConfig(XMLConfig: TXMLConfig; const Path: string; - DoSwitchPathDelims: boolean); + UsePathDelim: TPathDelimSwitch); public property FlagType: TBuildModeFlagType read FFlagType write FFlagType; property Value: string read FValue write FValue; @@ -180,7 +180,7 @@ type procedure LoadFromXMLConfig(XMLConfig: TXMLConfig; const Path: string; DoSwitchPathDelims: boolean); procedure SaveToXMLConfig(XMLConfig: TXMLConfig; const Path: string; - DoSwitchPathDelims: boolean); + UsePathDelim: TPathDelimSwitch); public property Name: string read FName write SetName; property Graph: TBuildModeGraph read FGraph; @@ -198,31 +198,44 @@ type TBuildModeGraph = class private + FChangeStamp: integer; FEvaluator: TExpressionEvaluator; FFirstBuildVars: TIDEBuildVariables; // all active lists of build variables FModes: TFPList; FActiveModes: TFPList; + FModified: boolean; FSelectedMode: TBuildMode; procedure Changed; function GetActiveModes(Index: integer): TBuildMode; function GetModes(Index: integer): TBuildMode; + procedure SetModified(const AValue: boolean); procedure SetSelectedMode(const AValue: TBuildMode); procedure UpdateActiveModes; public constructor Create; destructor Destroy; override; procedure ClearModes; + procedure IncreaseChangeStamp; + property ChangeStamp: integer read FChangeStamp; + function AddMode(aName: string): TBuildMode; + procedure LoadFromXMLConfig(XMLConfig: TXMLConfig; const Path: string; + Merge, DoSwitchPathDelims: boolean); + procedure SaveToXMLConfig(XMLConfig: TXMLConfig; const Path: string; + SaveData, SaveSession: boolean; + UsePathDelim: TPathDelimSwitch); function FindVarWithIdentifier(Identifier: string; out BuildVars: TIDEBuildVariables; - out BuildVar: TIDEBuildVariable): boolean; + out BuildVar: TIDEBuildVariable): boolean; function GetUniqueVarName(CheckToo: TIDEBuildVariables): string; + function GetUniqueModeName(Ignore, CheckToo: TBuildMode): string; property Evaluator: TExpressionEvaluator read FEvaluator; - property SelectedMode: TBuildMode read FSelectedMode write SetSelectedMode; + property SelectedMode: TBuildMode read FSelectedMode write SetSelectedMode;// saved to project session function ModeCount: integer; property Modes[Index: integer]: TBuildMode read GetModes; function IndexOfMode(const aName: string): integer; function FindModeWithName(const aName: string): TBuildMode; function ActiveModeCount: integer; property ActiveModes[Index: integer]: TBuildMode read GetActiveModes; + property Modified: boolean read FModified write SetModified; end; { TDefaultBuildModeGraph } @@ -3584,10 +3597,19 @@ begin Result:=TBuildMode(FModes[Index]); end; +procedure TBuildModeGraph.SetModified(const AValue: boolean); +begin + if AValue then + IncreaseChangeStamp; + if FModified=AValue then exit; + FModified:=AValue; +end; + procedure TBuildModeGraph.SetSelectedMode(const AValue: TBuildMode); begin if FSelectedMode=AValue then exit; FSelectedMode:=AValue; + Modified:=true; UpdateActiveModes; end; @@ -3643,11 +3665,107 @@ procedure TBuildModeGraph.ClearModes; var i: Integer; begin + if FModes.Count=0 then exit; FActiveModes.Clear; for i:=FModes.Count-1 downto 0 do begin TObject(FModes[i]).Free; end; FModes.Clear; + Modified:=true; +end; + +procedure TBuildModeGraph.IncreaseChangeStamp; +begin + if FChangeStampnil then exit; + Result:=TBuildMode.Create(Self,aName); + FModes.Add(Result); + Modified:=true; +end; + +procedure TBuildModeGraph.LoadFromXMLConfig(XMLConfig: TXMLConfig; + const Path: string; Merge, DoSwitchPathDelims: boolean); +// Merge=false: clear modes and load them +// Merge=false: keep modes, add/update modes +var + NewCnt: LongInt; + i: Integer; + SubPath: String; + ModeName: String; + CurMode: TBuildMode; +begin + // load modes + if not Merge then + ClearModes; + + // modes can reference each other, so first create all modes + NewCnt:=XMLConfig.GetValue('Modes/Count',0); + for i:=0 to NewCnt-1 do begin + SubPath:=Path+'Modes/Mode'+IntToStr(i)+'/'; + ModeName:=XMLConfig.GetValue(SubPath+'Name/Value',''); + if (ModeName='') then continue; + CurMode:=AddMode(ModeName); + if CurMode=nil then continue; // invalid name + end; + + // load modes + for i:=0 to NewCnt-1 do begin + SubPath:=Path+'Modes/Mode'+IntToStr(i)+'/'; + ModeName:=XMLConfig.GetValue(SubPath+'Name/Value',''); + if (ModeName='') then continue; + CurMode:=FindModeWithName(ModeName); + if CurMode=nil then continue; + CurMode.LoadFromXMLConfig(XMLConfig,SubPath,DoSwitchPathDelims); + end; + + // selected mode + ModeName:=XMLConfig.GetValue('Modes/Selected',''); + FSelectedMode:=nil; + if ModeName<>'' then + FSelectedMode:=FindModeWithName(ModeName); + UpdateActiveModes; + + Modified:=false; +end; + +procedure TBuildModeGraph.SaveToXMLConfig(XMLConfig: TXMLConfig; + const Path: string; SaveData, SaveSession: boolean; + UsePathDelim: TPathDelimSwitch); +var + SavedCnt: Integer; + i: Integer; + CurMode: TBuildMode; + s: String; +begin + // save modes + SavedCnt:=0; + for i:=0 to ModeCount-1 do begin + CurMode:=Modes[i]; + if (CurMode.StoredInSession and SaveSession) + or ((not CurMode.StoredInSession) and (SaveData)) then + begin + CurMode.SaveToXMLConfig(XMLConfig,Path+'Modes/Mode'+IntToStr(SavedCnt)+'/', + UsePathDelim); + inc(SavedCnt); + end; + end; + XMLConfig.SetDeleteValue('Modes/Count',SavedCnt,0); + + if FSelectedMode<>nil then + s:=FSelectedMode.Name + else + s:=''; + XMLConfig.SetDeleteValue('Modes/Selected',s,''); + + Modified:=true; end; function TBuildModeGraph.FindVarWithIdentifier(Identifier: string; out @@ -3677,6 +3795,24 @@ begin and ((CheckToo=nil) or (CheckToo.IndexOfIdentifier(Result)<0)); end; +function TBuildModeGraph.GetUniqueModeName(Ignore, CheckToo: TBuildMode): string; +var + i: Integer; + CurMode: TBuildMode; +begin + i:=0; + while true do begin + inc(i); + Result:='Mode'+IntToStr(i); + if (CheckToo<>nil) and (SysUtils.CompareText(CheckToo.Name,Result)=0) then + continue; + CurMode:=FindModeWithName(Result); + if (CurMode<>nil) and (CurMode<>Ignore) then + continue; + exit; + end; +end; + function TBuildModeGraph.ModeCount: integer; begin Result:=FModes.Count; @@ -4738,7 +4874,8 @@ begin for i:=0 to NewCnt-1 do begin Flag:=TBuildModeFlag.Create; FFlags.Add(Flag); - Flag.LoadFromXMLConfig(XMLConfig,Path+'Flags/Item'+IntToStr(i)+'/',DoSwitchPathDelims); + Flag.LoadFromXMLConfig(XMLConfig,Path+'Flags/Item'+IntToStr(i)+'/', + DoSwitchPathDelims); end; NewCnt:=XMLConfig.GetValue(Path+'Includes/Count',0); @@ -4750,17 +4887,19 @@ begin end; procedure TBuildMode.SaveToXMLConfig(XMLConfig: TXMLConfig; const Path: string; - DoSwitchPathDelims: boolean); + UsePathDelim: TPathDelimSwitch); var i: Integer; begin XMLConfig.SetDeleteValue(Path+'Name/Value',FName,''); XMLConfig.SetDeleteValue(Path+'Flags/Count',FlagCount,0); for i:=0 to FlagCount-1 do - Flags[i].SaveToXMLConfig(XMLConfig,Path+'Flags/Item'+IntToStr(i)+'/',DoSwitchPathDelims); + Flags[i].SaveToXMLConfig(XMLConfig,Path+'Flags/Item'+IntToStr(i)+'/', + UsePathDelim); XMLConfig.SetDeleteValue(Path+'Includes/Count',IncludeCount,0); for i:=0 to IncludeCount-1 do - XMLConfig.SetDeleteValue(Path+'Includes/Mode'+IntToStr(i)+'/Name',Includes[i].Name,''); + XMLConfig.SetDeleteValue(Path+'Includes/Mode'+IntToStr(i)+'/Name', + Includes[i].Name,''); end; { TBuildModeFlag } @@ -4787,13 +4926,15 @@ begin end; procedure TBuildModeFlag.SaveToXMLConfig(XMLConfig: TXMLConfig; - const Path: string; DoSwitchPathDelims: boolean); + const Path: string; UsePathDelim: TPathDelimSwitch); var s: String; begin XMLConfig.SetDeleteValue(Path+'Type',BuildModeFlagTypeNames[FFlagType], BuildModeFlagTypeNames[bmftAddCustomOption]); - s:=SwitchPathDelims(FValue,DoSwitchPathDelims and (FFlagType in BuildModeFlagPaths)); + s:=FValue; + if FFlagType in BuildModeFlagPaths then + SwitchPathDelims(FValue,UsePathDelim); XMLConfig.SetDeleteValue(Path+'Value',s,''); XMLConfig.SetDeleteValue(Path+'Variable',FVariable,''); end; diff --git a/ide/project.pp b/ide/project.pp index 29228da8bf..ba127a36f5 100644 --- a/ide/project.pp +++ b/ide/project.pp @@ -568,6 +568,7 @@ type FAutoCreateForms: boolean; FAutoOpenDesignerFormsDisabled: boolean; FBookmarks: TProjectBookmarkList; + FBuildModes: TBuildModeGraph; fChanged: boolean; FCompilerOptions: TProjectCompilerOptions; fCurStorePathDelim: TPathDelimSwitch; // used by OnLoadSaveFilename @@ -629,6 +630,7 @@ type const OldUnitName, NewUnitName: string; CheckIfAllowed: boolean; var Allowed: boolean); procedure SetAutoOpenDesignerFormsDisabled(const AValue: boolean); + procedure SetBuildModes(const AValue: TBuildModeGraph); procedure SetCompilerOptions(const AValue: TProjectCompilerOptions); procedure SetMainProject(const AValue: boolean); procedure SetSkipCheckLCLInterfaces(const AValue: boolean); @@ -827,6 +829,7 @@ type read FAutoOpenDesignerFormsDisabled write SetAutoOpenDesignerFormsDisabled; property Bookmarks: TProjectBookmarkList read FBookmarks write FBookmarks; + property BuildModes: TBuildModeGraph read FBuildModes write SetBuildModes; property SkipCheckLCLInterfaces: boolean read FSkipCheckLCLInterfaces write SetSkipCheckLCLInterfaces; property CompilerOptions: TProjectCompilerOptions @@ -1879,6 +1882,7 @@ begin inherited Create(ProjectDescription); fActiveEditorIndexAtStart := -1; + FBuildModes:=TBuildModeGraph.Create; FSkipCheckLCLInterfaces:=false; FAutoCreateForms := true; FBookmarks := TProjectBookmarkList.Create; @@ -1924,6 +1928,7 @@ begin FreeThenNil(FRunParameterOptions); FreeThenNil(FCompilerOptions); FreeThenNil(FDefineTemplates); + FreeThenNil(FBuildModes); inherited Destroy; end; @@ -2118,9 +2123,13 @@ begin RunParameterOptions.Save(xmlconfig,Path,fCurStorePathDelim); // save dependencies - SavePkgDependencyList(XMLConfig,Path+'RequiredPackages/', + SavePkgDependencyList(xmlconfig,Path+'RequiredPackages/', FFirstRequiredDependency,pdlRequires,fCurStorePathDelim); + // save build modes + BuildModes.SaveToXMLConfig(xmlconfig,Path+'BuildModes/',true,SaveSessionInfoInLPI, + fCurStorePathDelim); + // save units SaveUnits(XMLConfig,Path,true,SaveSessionInfoInLPI); @@ -2189,12 +2198,17 @@ begin try Path:='ProjectSession/'; fCurStorePathDelim:=SessionStorePathDelim; - xmlconfig.SetDeleteValue(Path+'PathDelim/Value',PathDelimSwitchToDelim[fCurStorePathDelim],'/'); + xmlconfig.SetDeleteValue(Path+'PathDelim/Value', + PathDelimSwitchToDelim[fCurStorePathDelim],'/'); xmlconfig.SetValue(Path+'Version/Value',ProjectInfoFileVersion); // save all units SaveUnits(XMLConfig,Path,true,true); - + + // build modes + FBuildModes.SaveToXMLConfig(xmlconfig,Path+'BuildModes/',false,true, + fCurStorePathDelim); + // save session SaveSessionInfo(XMLConfig,Path); @@ -2474,6 +2488,10 @@ begin ProjectSessionStorageNames[pssInProjectInfo])); //DebugLn('TProject.ReadProject SessionStorage=',dbgs(ord(SessionStorage)),' ProjectSessionFile=',ProjectSessionFile); + // build modes + FBuildModes.LoadFromXMLConfig(xmlconfig,Path+'BuildModes/',false, + fPathDelimChanged); + NewMainUnitID := xmlconfig.GetValue(Path+'General/MainUnit/Value', -1); AutoCreateForms := xmlconfig.GetValue( Path+'General/AutoCreateForms/Value', true); @@ -2555,6 +2573,10 @@ begin FileVersion:=XMLConfig.GetValue(Path+'Version/Value',0); + // load user sepcific build modes + FBuildModes.LoadFromXMLConfig(xmlconfig,Path+'BuildModes/',true, + fPathDelimChanged); + // load session info LoadSessionInfo(XMLConfig,Path,true); @@ -2715,6 +2737,8 @@ var i:integer; begin BeginUpdate(true); + FBuildModes.ClearModes; + // break and free removed dependencies while FFirstRemovedDependency<>nil do DeleteRemovedDependency(FFirstRemovedDependency); @@ -4219,6 +4243,12 @@ begin FAutoOpenDesignerFormsDisabled:=AValue; end; +procedure TProject.SetBuildModes(const AValue: TBuildModeGraph); +begin + if FBuildModes=AValue then exit; + FBuildModes:=AValue; +end; + procedure TProject.SetCompilerOptions(const AValue: TProjectCompilerOptions); begin if FCompilerOptions=AValue then exit;