lazarus/ide/project.pp
mattias 7b213bc79f fixed win32 intf menu height from Wojciech
git-svn-id: trunk@4827 -
2003-11-22 23:56:33 +00:00

3159 lines
99 KiB
ObjectPascal

{ $Id$ }
{
/***************************************************************************
project.pp - project utility class file
-----------------------------------------
TProject is responsible for managing a complete project.
Initial Revision : Sun Mar 28 23:15:32 CST 1999
***************************************************************************/
***************************************************************************
* *
* This source is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This code is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* General Public License for more details. *
* *
* A copy of the GNU General Public License is available on the World *
* Wide Web at <http://www.gnu.org/copyleft/gpl.html>. You can also *
* obtain it by writing to the Free Software Foundation, *
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
***************************************************************************
}
unit Project;
{$mode objfpc}{$H+}
{$ifdef Trace}
{$ASSERTIONS ON}
{$endif}
interface
{$I ide.inc}
uses
{$IFDEF IDE_MEM_CHECK}
MemCheck,
{$ENDIF}
Classes, SysUtils, LCLIntf, LCLType, Laz_XMLCfg, LazConf, CompilerOptions,
FileCtrl, CodeToolManager, CodeCache, Forms, Controls, EditorOptions, Dialogs,
IDEProcs, RunParamsOpts, ProjectDefs, EditDefineTree, DefineTemplates,
PackageDefs;
type
TUnitInfo = class;
TProject = class;
TOnFileBackup = function(const FileToBackup:string;
IsPartOfProject:boolean):TModalResult of object;
TOnUnitNameChange = procedure(AnUnitInfo: TUnitInfo;
const OldUnitName, NewUnitName: string;
CheckIfAllowed: boolean;
var Allowed: boolean) of object;
TOnLoadProjectInfo = procedure(TheProject: TProject;
XMLConfig: TXMLConfig) of object;
TOnSaveProjectInfo = procedure(TheProject: TProject;
XMLConfig: TXMLConfig) of object;
TUnitInfoList = (
uilPartOfProject,
uilWithEditorIndex,
uilWithComponent,
uilLoaded,
uilAutoRevertLocked
);
//---------------------------------------------------------------------------
TUnitInfo = class(TObject)
private
fAutoRevertLockCount: integer;
fBookmarks: TFileBookmarks;
FBuildFileIfActive: boolean;
fCursorPos: TPoint;
fCustomHighlighter: boolean; // do not change highlighter on file extension change
fEditorIndex: integer;
fFileName: string;
fFileReadOnly: Boolean;
fComponent: TComponent;
fComponentName: string; { classname is always T<ComponentName>
this attribute contains the component name,
even if the unit is not loaded,
or the designer form is not created.
A component can be a TForm or a TDataModule }
fComponentResourceName: string;
fHasResources: boolean; // source has resource file
FIgnoreFileDateOnDiskValid: boolean;
FIgnoreFileDateOnDisk: longint;
fIsPartOfProject: boolean;
fLoaded: Boolean; // loaded in the source editor
fModified: boolean;
fNext, fPrev: array[TUnitInfoList] of TUnitInfo;
fOnFileBackup: TOnFileBackup;
fOnLoadSaveFilename: TOnLoadSaveFilename;
fOnUnitNameChange: TOnUnitNameChange;
FProject: TProject;
FResourceFilename: string;
FRunFileIfActive: boolean;
fSource: TCodeBuffer;
fSyntaxHighlighter: TLazSyntaxHighlighter;
fTopLine: integer;
fUnitName: String;
fUsageCount: extended;
fUserReadOnly: Boolean;
function GetFileName: string;
function GetHasResources:boolean;
function GetNextAutoRevertLockedUnit: TUnitInfo;
function GetNextLoadedUnit: TUnitInfo;
function GetNextPartOfProject: TUnitInfo;
function GetNextUnitWithComponent: TUnitInfo;
function GetNextUnitWithEditorIndex: TUnitInfo;
function GetPrevAutoRevertLockedUnit: TUnitInfo;
function GetPrevLoadedUnit: TUnitInfo;
function GetPrevPartOfProject: TUnitInfo;
function GetPrevUnitWithComponent: TUnitInfo;
function GetPrevUnitWithEditorIndex: TUnitInfo;
procedure SetBuildFileIfActive(const AValue: boolean);
procedure SetEditorIndex(const AValue: integer);
procedure SetFileReadOnly(const AValue: Boolean);
procedure SetComponent(const AValue: TComponent);
procedure SetIsPartOfProject(const AValue: boolean);
procedure SetLoaded(const AValue: Boolean);
procedure SetProject(const AValue: TProject);
procedure SetRunFileIfActive(const AValue: boolean);
procedure SetSource(ABuffer: TCodeBuffer);
procedure SetUnitName(const NewUnitName:string);
procedure SetUserReadOnly(const NewValue: boolean);
protected
procedure UpdateList(ListType: TUnitInfoList; Add: boolean);
public
constructor Create(ACodeBuffer: TCodeBuffer);
destructor Destroy; override;
function ChangedOnDisk(CompareOnlyLoadSaveTime: boolean): boolean;
function IsAutoRevertLocked: boolean;
function IsMainUnit: boolean;
function IsVirtual: boolean;
function NeedsSaveToDisk: boolean;
function ReadOnly: boolean;
function ReadUnitSource(ReadUnitName,Revert:boolean): TModalResult;
function ShortFilename: string;
function WriteUnitSource: TModalResult;
function WriteUnitSourceToFile(const AFileName: string): TModalResult;
procedure Clear;
procedure CreateStartCode(NewUnitType: TNewUnitType;
const NewUnitName: string);
procedure DecreaseAutoRevertLock;
procedure IgnoreCurrentFileDateOnDisk;
procedure IncreaseAutoRevertLock;
procedure LoadFromXMLConfig(XMLConfig: TXMLConfig; const Path: string);
procedure ReadUnitNameFromSource(TryCache: boolean);
function CreateUnitName: string;
procedure SaveToXMLConfig(XMLConfig: TXMLConfig; const Path: string);
procedure UpdateUsageCount(Min, IfBelowThis, IncIfBelow: extended);
procedure UpdateUsageCount(TheUsage: TUnitUsage; Factor: extended);
{ Properties }
public
// Unit lists
property NextUnitWithEditorIndex: TUnitInfo read GetNextUnitWithEditorIndex;
property PrevUnitWithEditorIndex: TUnitInfo read GetPrevUnitWithEditorIndex;
property NextUnitWithComponent: TUnitInfo read GetNextUnitWithComponent;
property PrevUnitWithComponent: TUnitInfo read GetPrevUnitWithComponent;
property NextLoadedUnit: TUnitInfo read GetNextLoadedUnit;
property PrevLoadedUnit: TUnitInfo read GetPrevLoadedUnit;
property NextAutoRevertLockedUnit: TUnitInfo read GetNextAutoRevertLockedUnit;
property PrevAutoRevertLockedUnit: TUnitInfo read GetPrevAutoRevertLockedUnit;
property NextPartOfProject: TUnitInfo read GetNextPartOfProject;
property PrevPartOfProject: TUnitInfo read GetPrevPartOfProject;
public
property Bookmarks: TFileBookmarks read FBookmarks write FBookmarks;
property BuildFileIfActive: boolean read FBuildFileIfActive write SetBuildFileIfActive;
property Component: TComponent read fComponent write SetComponent;
property ComponentName: string read fComponentName write fComponentName;
property ComponentResourceName: string read fComponentResourceName
write fComponentResourceName;
property CursorPos: TPoint read fCursorPos write fCursorPos;
property CustomHighlighter: boolean
read fCustomHighlighter write fCustomHighlighter;
property EditorIndex:integer read fEditorIndex write SetEditorIndex;
property Filename: String read GetFilename;
property FileReadOnly: Boolean read fFileReadOnly write SetFileReadOnly;
property HasResources: boolean read GetHasResources write fHasResources;
property IsPartOfProject: boolean
read fIsPartOfProject write SetIsPartOfProject;
property Loaded: Boolean read fLoaded write SetLoaded;
property Modified: boolean read fModified write fModified;
property OnFileBackup: TOnFileBackup read fOnFileBackup write fOnFileBackup;
property OnLoadSaveFilename: TOnLoadSaveFilename
read fOnLoadSaveFilename write fOnLoadSaveFilename;
property OnUnitNameChange: TOnUnitNameChange
read fOnUnitNameChange write fOnUnitNameChange;
property Project: TProject read FProject write SetProject;
property ResourceFileName: string
read FResourceFilename write FResourceFilename;
property RunFileIfActive: boolean read FRunFileIfActive write SetRunFileIfActive;
property Source: TCodeBuffer read fSource write SetSource;
property SyntaxHighlighter: TLazSyntaxHighlighter
read fSyntaxHighlighter write fSyntaxHighlighter;
property TopLine: integer read fTopLine write fTopLine;
property UnitName: String read fUnitName write SetUnitName;
property UserReadOnly: Boolean read fUserReadOnly write SetUserReadOnly;
end;
//---------------------------------------------------------------------------
{ TProjectCompilerOptions }
TProjectCompilerOptions = class(TCompilerOptions)
private
FOwnerProject: TProject;
public
constructor Create(TheProject: TProject);
function GetOwnerName: string; override;
function GetDefaultMainSourceFileName: string; override;
procedure GetInheritedCompilerOptions(var OptionsList: TList); override;
public
property OwnerProject: TProject read FOwnerProject;
end;
{ TProjectDefineTemplates }
TProjectDefineTemplatesFlag = (
ptfFlagsChanged
);
TProjectDefineTemplatesFlags = set of TProjectDefineTemplatesFlag;
TProjectDefineTemplates = class
private
FFlags: TProjectDefineTemplatesFlags;
FMain: TDefineTemplate;
FProjectDir: TDefineTemplate;
FProject: TProject;
FUpdateLock: integer;
procedure UpdateMain;
public
constructor Create(OwnerProject: TProject);
destructor Destroy; override;
procedure Clear;
procedure BeginUpdate;
procedure EndUpdate;
procedure CompilerFlagsChanged;
procedure AllChanged;
procedure UpdateGlobalValues;
public
property Owner: TProject read FProject;
property Main: TDefineTemplate read FMain;
end;
{ TProject }
TProjectType = // for a description see ProjectTypeDescriptions below
(ptApplication, ptProgram, ptCustomProgram, ptCGIApplication);
TProjectFlag = (
pfSaveClosedUnits, // save info about closed files (not part of project)
pfSaveOnlyProjectUnits // save no info about foreign files
);
TProjectFlags = set of TProjectFlag;
TProjectFileSearchFlag = (
pfsfResolveFileLinks,
pfsfOnlyEditorFiles
);
TProjectFileSearchFlags = set of TProjectFileSearchFlag;
TEndUpdateProjectEvent =
procedure(Sender: TObject; ProjectChanged: boolean) of object;
TProject = class(TObject)
private
fActiveEditorIndexAtStart: integer;
FAutoCreateForms: boolean;
fBookmarks: TProjectBookmarkList;
fChanged: boolean;
fCompilerOptions: TProjectCompilerOptions;
FDefineTemplates: TProjectDefineTemplates;
FFirstRemovedDependency: TPkgDependency;
FFirstRequiredDependency: TPkgDependency;
fFirst: array[TUnitInfoList] of TUnitInfo;
FFlags: TProjectFlags;
fIconPath: String;
fJumpHistory: TProjectJumpHistory;
fLastReadLPIFileDate: TDateTime;
fLastReadLPIFilename: string;
fMainUnitID: Integer; // only for ptApplication, ptProgram, ptCGIApplication
fModified: boolean;
FOnBeginUpdate: TNotifyEvent;
FOnEndUpdate: TEndUpdateProjectEvent;
fOnFileBackup: TOnFileBackup;
FOnLoadProjectInfo: TOnLoadProjectInfo;
FOnSaveProjectInfo: TOnSaveProjectInfo;
fPathDelimChanged: boolean;
fProjectDirectory: string;
fProjectInfoFile: String; // the lpi filename
fProjectType: TProjectType;
fPublishOptions: TPublishProjectOptions;
fRunParameterOptions: TRunParamsOptions;
fTargetFileExt: String;
fTitle: String;
fUnitList: TList; // list of _all_ units (TUnitInfo)
FUpdateLock: integer;
xmlconfig: TXMLConfig;
function GetFirstAutoRevertLockedUnit: TUnitInfo;
function GetFirstLoadedUnit: TUnitInfo;
function GetFirstPartOfProject: TUnitInfo;
function GetFirstUnitWithComponent: TUnitInfo;
function GetFirstUnitWithEditorIndex: TUnitInfo;
function GetMainFilename: String;
function GetMainUnitInfo: TUnitInfo;
function GetProjectInfoFile: string;
function GetTargetFilename: string;
function GetUnits(Index: integer): TUnitInfo;
function JumpHistoryCheckPosition(
APosition:TProjectJumpHistoryPosition): boolean;
function OnUnitFileBackup(const Filename: string;
IsPartOfProject:boolean): TModalResult;
procedure OnLoadSaveFilename(var AFilename: string; Load: boolean);
procedure OnUnitNameChange(AnUnitInfo: TUnitInfo;
const OldUnitName, NewUnitName: string;
CheckIfAllowed: boolean; var Allowed: boolean);
procedure SetFlags(const AValue: TProjectFlags);
procedure SetMainUnitID(const AValue: Integer);
procedure SetModified(const AValue: boolean);
procedure SetProjectInfoFile(const NewFilename: string);
procedure SetTargetFilename(const NewTargetFilename: string);
procedure SetUnits(Index:integer; AUnitInfo: TUnitInfo);
procedure UpdateProjectDirectory;
protected
// special unit lists
procedure AddToList(AnUnitInfo: TUnitInfo; ListType: TUnitInfoList);
procedure RemoveFromList(AnUnitInfo: TUnitInfo; ListType: TUnitInfoList);
procedure AddToOrRemoveFromAutoRevertLockedList(AnUnitInfo: TUnitInfo);
procedure AddToOrRemoveFromEditorWithIndexList(AnUnitInfo: TUnitInfo);
procedure AddToOrRemoveFromComponentList(AnUnitInfo: TUnitInfo);
procedure AddToOrRemoveFromLoadedList(AnUnitInfo: TUnitInfo);
procedure AddToOrRemoveFromPartOfProjectList(AnUnitInfo: TUnitInfo);
public
constructor Create(TheProjectType: TProjectType);
destructor Destroy; override;
procedure Clear;
procedure BeginUpdate(Change: boolean);
procedure EndUpdate;
// load/save
function IsVirtual: boolean;
function SomethingModified: boolean;
procedure MainSourceFilenameChanged;
procedure GetUnitsChangedOnDisk(var AnUnitList: TList);
function ReadProject(const LPIFilename: string): TModalResult;
function WriteProject(ProjectWriteFlags: TProjectWriteFlags;
const OverrideProjectInfoFile: string): TModalResult;
// units
function UnitCount:integer;
function NewUniqueUnitName(NewUnitType:TNewUnitType): string;
function NewUniqueComponentName(NewUnitType:TNewUnitType): string;
procedure AddUnit(AnUnit: TUnitInfo; AddToProjectFile: boolean);
procedure RemoveUnit(Index: integer);
// search
function IndexOf(AUnitInfo: TUnitInfo): integer;
function IndexOfUnitWithName(const AnUnitName: string;
OnlyProjectUnits:boolean; IgnoreUnit: TUnitInfo): integer;
function IndexOfUnitWithComponent(AComponent: TComponent;
OnlyProjectUnits:boolean; IgnoreUnit: TUnitInfo): integer;
function IndexOfUnitWithComponentName(const AComponentName: string;
OnlyProjectUnits:boolean; IgnoreUnit: TUnitInfo): integer;
function IndexOfFilename(const AFilename: string): integer;
function IndexOfFilename(const AFilename: string;
SearchFlags: TProjectFileSearchFlags): integer;
function ProjectUnitWithFilename(const AFilename: string): TUnitInfo;
function ProjectUnitWithUnitname(const AnUnitName: string): TUnitInfo;
function UnitWithEditorIndex(Index:integer): TUnitInfo;
Function UnitWithComponent(AComponent: TComponent): TUnitInfo;
function UnitInfoWithFilename(const AFilename: string): TUnitInfo;
function UnitWithUnitname(const AnUnitname: string): TUnitInfo;
// units in editor
procedure CloseEditorIndex(EditorIndex:integer);
procedure InsertEditorIndex(EditorIndex:integer);
procedure MoveEditorIndex(OldEditorIndex, NewEditorIndex: integer);
// Application.CreateForm statements
function AddCreateFormToProjectFile(const AClassName, AName:string):boolean;
function RemoveCreateFormFromProjectFile(const AClassName,
AName: string):boolean;
function FormIsCreatedInProjectFile(const AClassname, AName:string):boolean;
// uses section
function UnitIsUsed(const ShortUnitName:string):boolean;
// resources
function GetMainResourceFilename(AnUnitInfo: TUnitInfo): string;
function GetResourceFile(AnUnitInfo: TUnitInfo; Index:integer):TCodeBuffer;
// filenames and fileinfo
function RemoveProjectPathFromFilename(const AFilename: string): string;
function FileIsInProjectDir(const AFilename: string): boolean;
procedure GetVirtualDefines(DefTree: TDefineTree; DirDef: TDirectoryDefines);
function SearchFile(const Filename,SearchPaths,InitialDir:string):string;
procedure ShortenFilename(var AFilename: string);
procedure LongenFilename(var AFilename: string);
// bookmarks
procedure SetBookmark(AnUnitInfo: TUnitInfo; X,Y,ID: integer);
procedure MergeBookmarks(AnUnitInfo: TUnitInfo);
// dependencies
function FindDependencyByName(const PackageName: string): TPkgDependency;
function RequiredDepByIndex(Index: integer): TPkgDependency;
function RemovedDepByIndex(Index: integer): TPkgDependency;
procedure AddRequiredDependency(Dependency: TPkgDependency);
procedure RemoveRequiredDependency(Dependency: TPkgDependency);
procedure DeleteRequiredDependency(Dependency: TPkgDependency);
procedure DeleteRemovedDependency(Dependency: TPkgDependency);
procedure RemoveRemovedDependency(Dependency: TPkgDependency);
procedure ReaddRemovedDependency(Dependency: TPkgDependency);
procedure MoveRequiredDependencyUp(Dependency: TPkgDependency);
procedure MoveRequiredDependencyDown(Dependency: TPkgDependency);
function Requires(APackage: TLazPackage): boolean;
procedure GetAllRequiredPackages(var List: TList);
public
property ActiveEditorIndexAtStart: integer read fActiveEditorIndexAtStart
write fActiveEditorIndexAtStart;
property AutoCreateForms: boolean
read FAutoCreateForms write FAutoCreateForms;
property Bookmarks: TProjectBookmarkList read fBookmarks write fBookmarks;
property CompilerOptions: TProjectCompilerOptions
read fCompilerOptions write fCompilerOptions;
property DefineTemplates: TProjectDefineTemplates read FDefineTemplates;
property FirstAutoRevertLockedUnit: TUnitInfo read GetFirstAutoRevertLockedUnit;
property FirstLoadedUnit: TUnitInfo read GetFirstLoadedUnit;
property FirstPartOfProject: TUnitInfo read GetFirstPartOfProject;
property FirstRemovedDependency: TPkgDependency
read FFirstRemovedDependency;
property FirstRequiredDependency: TPkgDependency
read FFirstRequiredDependency;
property FirstUnitWithEditorIndex: TUnitInfo read GetFirstUnitWithEditorIndex;
property FirstUnitWithComponent: TUnitInfo read GetFirstUnitWithComponent;
property Flags: TProjectFlags read FFlags write SetFlags;
property IconPath: String read fIconPath write fIconPath;
property JumpHistory: TProjectJumpHistory
read fJumpHistory write fJumpHistory;
property MainFilename: String read GetMainFilename;
property MainUnitID: Integer read fMainUnitID write SetMainUnitID;
property MainUnitInfo: TUnitInfo read GetMainUnitInfo;
property Modified: boolean read fModified write SetModified;
property OnBeginUpdate: TNotifyEvent read FOnBeginUpdate write FOnBeginUpdate;
property OnEndUpdate: TEndUpdateProjectEvent read FOnEndUpdate write FOnEndUpdate;
property OnFileBackup: TOnFileBackup read fOnFileBackup write fOnFileBackup;
property OnSaveProjectInfo: TOnSaveProjectInfo read FOnSaveProjectInfo
write FOnSaveProjectInfo;
property OnLoadProjectInfo: TOnLoadProjectInfo read FOnLoadProjectInfo
write FOnLoadProjectInfo;
property ProjectDirectory: string read fProjectDirectory;
property ProjectInfoFile: string
read GetProjectInfoFile write SetProjectInfoFile;
property ProjectType: TProjectType read fProjectType write fProjectType;
property PublishOptions: TPublishProjectOptions
read fPublishOptions write fPublishOptions;
property RunParameterOptions: TRunParamsOptions read fRunParameterOptions;
property TargetFileExt: String read fTargetFileExt write fTargetFileExt;
property TargetFilename: string
read GetTargetFilename write SetTargetFilename;
property Title: String read fTitle write fTitle;
property Units[Index: integer]:TUnitInfo read GetUnits write SetUnits;
property UpdateLock: integer read FUpdateLock;
end;
const
ResourceFileExt = '.lrs';
ProjectTypeNames : array[TProjectType] of string = (
'Application', 'Program', 'Custom program', 'CGI Application'
);
ProjectTypeDescriptions : array[TProjectType] of string = (
// ptApplication
'Application'#13
+'A graphical lcl/freepascal program. The program file is '
+'automatically maintained by lazarus.'#13
// ptProgram
,'Program:'#13
+'A freepascal program. The program file is automatically '
+'maintained by lazarus.'
// ptCustomProgram
,'Custom program:'#13
+'A freepascal program.'
// ptCGIApplication
,'CGI Application'#13
+'A cgi freepascal program. The program file is '
+'automatically maintained by lazarus.'#13
);
ProjectDefaultExt : array[TProjectType] of string = (
'.lpr','.pas','.pas', 'pas'
);
UnitTypeDefaultExt: array[TNewUnitType] of string = (
'.pas', '.pas', '.pas', '.pas', '.pas', '.txt', '.pas'
);
DefaultProjectFlags = [pfSaveClosedUnits];
ProjectFlagNames : array[TProjectFlag] of string = (
'SaveClosedFiles', 'SaveOnlyProjectUnits'
);
function ProjectTypeNameToType(const s:string): TProjectType;
function ProjectFlagsToStr(Flags: TProjectFlags): string;
implementation
const
ProjectInfoFileVersion = 3;
function ProjectFlagsToStr(Flags: TProjectFlags): string;
var f: TProjectFlag;
begin
Result:='';
for f:=Low(TProjectFlag) to High(TProjectFlag) do begin
if f in Flags then begin
if Result='' then Result:=Result+',';
Result:=Result+ProjectFlagNames[f];
end;
end;
end;
function ProjectTypeNameToType(const s:string): TProjectType;
begin
for Result:=Low(TProjectType) to High(TProjectType) do
if (lowercase(ProjectTypeNames[Result])=lowercase(s)) then exit;
Result:=ptCustomProgram;
end;
{------------------------------------------------------------------------------
TUnitInfo Class
------------------------------------------------------------------------------}
{------------------------------------------------------------------------------
TUnitInfo Constructor
------------------------------------------------------------------------------}
constructor TUnitInfo.Create(ACodeBuffer: TCodeBuffer);
begin
inherited Create;
Assert(False, 'Project Unit Info Class Created');
FBookmarks:=TFileBookmarks.Create;
Clear;
Source := ACodeBuffer;
if Source=nil then
FFileName:='';
end;
{------------------------------------------------------------------------------
TUnitInfo Destructor
------------------------------------------------------------------------------}
destructor TUnitInfo.Destroy;
begin
Source:=nil;
FreeAndNil(FBookmarks);
Project:=nil;
inherited Destroy;
end;
{------------------------------------------------------------------------------
TUnitInfo WriteUnitSource
------------------------------------------------------------------------------}
function TUnitInfo.WriteUnitSource: TModalResult;
var
ACaption:string;
AText:string;
begin
if fSource=nil then begin
Result:=mrOk;
exit;
end;
if Assigned(fOnFileBackup) then begin
Result:=fOnFileBackup(fFilename,IsPartOfProject);
if Result=mrAbort then exit;
end;
repeat
if not fSource.Save then begin
ACaption:='Write error';
AText:='Unable to write file "'+Filename+'"!';
Result:=Application.MessageBox(PChar(AText),PChar(ACaption)
,MB_ABORTRETRYIGNORE);
if Result=mrAbort then exit;
if Result=mrIgnore then Result:=mrOk;
end else begin
Result:=mrOk;
FIgnoreFileDateOnDiskValid:=true;
end;
until Result<>mrRetry;
Result:=mrOk;
end;
function TUnitInfo.WriteUnitSourceToFile(const AFileName: string): TModalResult;
var
ACaption:string;
AText:string;
begin
if fSource=nil then begin
Result:=mrOk;
exit;
end;
if Assigned(fOnFileBackup) then begin
Result:=fOnFileBackup(fFilename,false);
if Result=mrAbort then exit;
end;
repeat
if not fSource.SaveToFile(AFileName) then begin
ACaption:='Write error';
AText:='Unable to write file "'+AFilename+'"!';
Result:=Application.MessageBox(PChar(AText),PChar(ACaption)
,MB_ABORTRETRYIGNORE);
if Result=mrAbort then exit;
if Result=mrIgnore then Result:=mrOk;
end else
Result:=mrOk;
until Result<>mrRetry;
Result:=mrOk;
end;
{------------------------------------------------------------------------------
TUnitInfo ReadUnitSource
------------------------------------------------------------------------------}
function TUnitInfo.ReadUnitSource(ReadUnitName,Revert:boolean): TModalResult;
var
ACaption:string;
AText:string;
NewSource: TCodeBuffer;
begin
repeat
NewSource:=CodeToolBoss.LoadFile(fFilename,true,Revert);
if NewSource=nil then begin
ACaption:='Read error';
AText:='Unable to read file "'+fFilename+'"!';
Result:=Application.MessageBox(PChar(AText),PChar(ACaption)
,MB_ABORTRETRYIGNORE);
if Result in [mrAbort,mrIgnore] then
exit;
end else begin
Source:=NewSource;
FIgnoreFileDateOnDiskValid:=true;
Result:=mrOk;
end;
until Result<>mrRetry;
if ReadUnitName then
fUnitName:=CodeToolBoss.GetSourceName(fSource,false);
Result:=mrOk;
end;
procedure TUnitInfo.ReadUnitNameFromSource(TryCache: boolean);
var
NewUnitName: String;
begin
if TryCache then begin
NewUnitName:=CodeToolBoss.GetCachedSourceName(Source);
if NewUnitName<>'' then begin
fUnitName:=NewUnitName;
exit;
end;
end;
fUnitName:=CodeToolBoss.GetSourceName(fSource,false);
end;
function TUnitInfo.CreateUnitName: string;
begin
Result:=UnitName;
if (Result='') and FilenameIsPascalUnit(Filename) then
Result:=ExtractFilenameOnly(Filename);
end;
{------------------------------------------------------------------------------
TUnitInfo Clear
------------------------------------------------------------------------------}
procedure TUnitInfo.Clear;
begin
FBookmarks.Clear;
FBuildFileIfActive:=false;
fComponent := nil;
fComponentName := '';
fComponentResourceName := '';
fCursorPos.X := -1;
fCursorPos.Y := -1;
fCustomHighlighter := false;
fEditorIndex := -1;
fFilename := '';
fFileReadOnly := false;
fHasResources := false;
FIgnoreFileDateOnDiskValid:=false;
fIsPartOfProject := false;
fModified := false;
FRunFileIfActive:=false;
fSyntaxHighlighter := lshText;
fTopLine := -1;
fUnitName := '';
fUsageCount:=-1;
fUserReadOnly := false;
if fSource<>nil then fSource.Clear;
Loaded := false;
end;
{------------------------------------------------------------------------------
TUnitInfo SaveToXMLConfig
------------------------------------------------------------------------------}
procedure TUnitInfo.SaveToXMLConfig(XMLConfig: TXMLConfig; const Path: string);
var AFilename:string;
begin
XMLConfig.SetDeleteValue(Path+'CursorPos/X',fCursorPos.X,-1);
XMLConfig.SetDeleteValue(Path+'CursorPos/Y',fCursorPos.Y,-1);
XMLConfig.SetDeleteValue(Path+'EditorIndex/Value',fEditorIndex,-1);
AFilename:=Filename;
if Assigned(fOnLoadSaveFilename) then
fOnLoadSaveFilename(AFilename,false);
XMLConfig.SetValue(Path+'Filename/Value',AFilename);
XMLConfig.SetDeleteValue(Path+'BuildFileIfActive/Value',
FBuildFileIfActive,false);
XMLConfig.SetDeleteValue(Path+'RunFileIfActive/Value',
FRunFileIfActive,false);
XMLConfig.SetDeleteValue(Path+'ComponentName/Value',fComponentName,'');
XMLConfig.SetDeleteValue(Path+'HasResources/Value',fHasResources,false);
XMLConfig.SetDeleteValue(Path+'IsPartOfProject/Value',fIsPartOfProject,false);
XMLConfig.SetDeleteValue(Path+'Loaded/Value',fLoaded,false);
XMLConfig.SetDeleteValue(Path+'ReadOnly/Value',fUserReadOnly,false);
AFilename:=FResourceFilename;
if Assigned(fOnLoadSaveFilename) then
fOnLoadSaveFilename(AFilename,false);
XMLConfig.SetDeleteValue(Path+'ResourceFilename/Value',AFilename,'');
XMLConfig.SetDeleteValue(Path+'SyntaxHighlighter/Value',
LazSyntaxHighlighterNames[fSyntaxHighlighter],
LazSyntaxHighlighterNames[lshFreePascal]);
XMLConfig.SetDeleteValue(Path+'TopLine/Value',fTopLine,-1);
XMLConfig.SetDeleteValue(Path+'UnitName/Value',fUnitName,'');
XMLConfig.SetDeleteValue(Path+'UsageCount/Value',round(fUsageCount),-1);
FBookmarks.SaveToXMLConfig(XMLConfig,Path+'Bookmarks/');
end;
{------------------------------------------------------------------------------
TUnitInfo LoadFromXMLConfig
------------------------------------------------------------------------------}
procedure TUnitInfo.LoadFromXMLConfig(XMLConfig: TXMLConfig; const Path: string);
var AFilename: string;
begin
CursorPos.X:=XMLConfig.GetValue(Path+'CursorPos/X',-1);
CursorPos.Y:=XMLConfig.GetValue(Path+'CursorPos/Y',-1);
EditorIndex:=XMLConfig.GetValue(Path+'EditorIndex/Value',-1);
AFilename:=XMLConfig.GetValue(Path+'Filename/Value','');
if Assigned(fOnLoadSaveFilename) then
fOnLoadSaveFilename(AFilename,true);
fFilename:=AFilename;
FBuildFileIfActive:=XMLConfig.GetValue(Path+'BuildFileIfActive/Value',
false);
FRunFileIfActive:=XMLConfig.GetValue(Path+'RunFileIfActive/Value',false);
fComponentName:=XMLConfig.GetValue(Path+'ComponentName/Value','');
if fComponentName='' then
fComponentName:=XMLConfig.GetValue(Path+'FormName/Value','');
HasResources:=XMLConfig.GetValue(Path+'HasResources/Value',false);
IsPartOfProject:=XMLConfig.GetValue(Path+'IsPartOfProject/Value',false);
Loaded:=XMLConfig.GetValue(Path+'Loaded/Value',false);
fUserReadOnly:=XMLConfig.GetValue(Path+'ReadOnly/Value',false);
AFilename:=XMLConfig.GetValue(Path+'ResourceFilename/Value','');
if (AFilename<>'') and Assigned(fOnLoadSaveFilename) then
fOnLoadSaveFilename(AFilename,true);
FResourceFilename:=AFilename;
if (FResourceFilename<>'')
and (FResourceFilename[length(FResourceFilename)]=PathDelim) then
FResourceFilename:='';
fSyntaxHighlighter:=StrToLazSyntaxHighlighter(XMLConfig.GetValue(
Path+'SyntaxHighlighter/Value',''));
fTopLine:=XMLConfig.GetValue(Path+'TopLine/Value',-1);
UnitName:=XMLConfig.GetValue(Path+'UnitName/Value','');
fUsageCount:=XMLConfig.GetValue(Path+'UsageCount/Value',-1);
if fUsageCount<1 then begin
UpdateUsageCount(uuIsLoaded,1);
if IsPartOfProject then
UpdateUsageCount(uuIsPartOfProject,1);
end;
FBookmarks.LoadFromXMLConfig(XMLConfig,Path+'Bookmarks/');
end;
procedure TUnitInfo.SetUnitName(const NewUnitName:string);
var Allowed:boolean;
begin
if (fUnitName<>NewUnitName) and (NewUnitName<>'') then begin
Allowed:=true;
if Assigned(fOnUnitNameChange) then
fOnUnitNameChange(Self,fUnitName,NewUnitName,false,Allowed);
// (ignore Allowed)
if (fSource<>nil) then begin
CodeToolBoss.RenameSource(fSource,NewUnitName);
end;
fUnitName:=NewUnitName;
if Project<>nil then Project.Modified:=true;
end;
end;
procedure TUnitInfo.UpdateList(ListType: TUnitInfoList; Add: boolean);
begin
if Project<>nil then begin
if Add then
Project.AddToList(Self,ListType)
else
Project.RemoveFromList(Self,ListType);
end else begin
fNext[ListType]:=nil;
fPrev[ListType]:=nil;
end;
end;
function TUnitInfo.GetFileName: string;
begin
if fSource<>nil then Result:=fSource.Filename
else Result:=fFileName;
end;
function TUnitInfo.IsVirtual: boolean;
begin
if fSource<>nil then
Result:=fSource.IsVirtual
else
Result:=(fFileName<>ExpandFileName(fFileName));
end;
function TUnitInfo.IsMainUnit: boolean;
begin
Result:=(Project<>nil) and (Project.MainUnitInfo=Self);
end;
procedure TUnitInfo.IncreaseAutoRevertLock;
begin
inc(fAutoRevertLockCount);
if (fAutoRevertLockCount=1) then begin
// activate lock
if (Source<>nil) then
Source.LockAutoDiskRevert;
if Project<>nil then
Project.AddToOrRemoveFromAutoRevertLockedList(Self);
end;
end;
procedure TUnitInfo.DecreaseAutoRevertLock;
begin
dec(fAutoRevertLockCount);
if (fAutoRevertLockCount=0) then begin
// deactivate lock
if (Source<>nil) then
Source.LockAutoDiskRevert;
if Project<>nil then
Project.AddToOrRemoveFromAutoRevertLockedList(Self);
end;
end;
function TUnitInfo.IsAutoRevertLocked: boolean;
begin
Result:=fAutoRevertLockCount>0;
end;
function TUnitInfo.ChangedOnDisk(CompareOnlyLoadSaveTime: boolean): boolean;
begin
Result:=(Source<>nil) and (Source.FileOnDiskHasChanged);
if Result
and (not CompareOnlyLoadSaveTime)
and FIgnoreFileDateOnDiskValid
and (FIgnoreFileDateOnDisk=Source.FileDateOnDisk) then
Result:=false;
if (not IsVirtual) and FileExists(Filename) then
FileReadOnly:=not FileIsWritable(Filename)
else
FileReadOnly:=false;
end;
procedure TUnitInfo.IgnoreCurrentFileDateOnDisk;
begin
if Source<>nil then begin
FIgnoreFileDateOnDiskValid:=true;
FIgnoreFileDateOnDisk:=Source.FileDateOnDisk;
end
end;
function TUnitInfo.ShortFilename: string;
begin
if Project<>nil then begin
Result:=Project.RemoveProjectPathFromFilename(Filename);
end else begin
Result:=Filename;
end;
end;
function TUnitInfo.NeedsSaveToDisk: boolean;
begin
Result:=IsVirtual or Modified or ChangedOnDisk(true)
or (not FileExists(Filename));
end;
procedure TUnitInfo.UpdateUsageCount(Min, IfBelowThis, IncIfBelow: extended);
begin
if fUsageCount<IfBelowThis then fUsageCount:=fUsageCount+IncIfBelow;
if fUsageCount<Min then fUsageCount:=Min;
end;
procedure TUnitInfo.UpdateUsageCount(TheUsage: TUnitUsage; Factor: extended);
begin
case TheUsage of
uuIsPartOfProject: UpdateUsageCount(20,200,2*Factor);
uuIsLoaded: UpdateUsageCount(10,100,1*Factor);
uuIsModified: UpdateUsageCount(10,0,0);
uuNotUsed: fUsageCount:=fUsageCount-(Factor/5);
end;
end;
function TUnitInfo.ReadOnly: boolean;
begin
Result:=UserReadOnly or FileReadOnly;
end;
procedure TUnitInfo.SetSource(ABuffer: TCodeBuffer);
begin
if fSource=ABuffer then exit;
if (fSource<>nil) and IsAutoRevertLocked then
fSource.UnlockAutoDiskRevert;
fSource:=ABuffer;
FIgnoreFileDateOnDiskValid:=false;
if (fSource<>nil) then begin
if IsAutoRevertLocked then
fSource.LockAutoDiskRevert;
fFileName:=fSource.FileName;
if (fProject<>nil) and (fProject.MainUnitInfo=Self) then
fProject.MainSourceFilenameChanged;
end;
end;
procedure TUnitInfo.SetUserReadOnly(const NewValue: boolean);
begin
fUserReadOnly:=NewValue;
if fSource<>nil then
fSource.ReadOnly:=ReadOnly;
end;
procedure TUnitInfo.CreateStartCode(NewUnitType: TNewUnitType;
const NewUnitName: string);
var AResourceFilename :string;
NewSource, LE: string;
function Beautified(const s: string): string;
begin
Result:=CodeToolBoss.SourceChangeCache.BeautifyCodeOptions.
BeautifyStatement(s,0);
end;
begin
if fSource=nil then exit;
NewSource:='';
LE:=EndOfLine;
if NewUnitType in [nuForm,nuUnit,nuDataModule,nuCGIDataModule] then begin
fUnitName:=NewUnitName;
AResourceFilename:=fUnitName+ResourceFileExt;
NewSource:=Beautified(
'unit '+fUnitName+';'+LE
+LE
+'{$mode objfpc}{$H+}'+LE
+LE
+'interface'+LE
+LE
+'uses'+LE);
case NewUnitType of
nuUnit:
begin
NewSource:=NewSource+Beautified(
' Classes, SysUtils;'+LE
+LE
+'implementation'+LE);
end;
nuForm, nuDataModule, nuCGIDataModule:
begin
if NewUnitType=nuForm then
NewSource:=NewSource+Beautified(
' Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs;'+LE
+LE
+'type'+LE)
else if NewUnitType=nuDataModule then
NewSource:=NewSource+Beautified(
' Classes, SysUtils, LResources, Forms, Controls, Dialogs;'+LE
+LE
+'type'+LE)
else if NewUnitType=nuCGIDataModule then
NewSource:=NewSource+Beautified(
' Classes, SysUtils, LResources, cgiModules;'+LE
+LE
+'type'+LE);
if NewUnitType=nuForm then
NewSource:=NewSource+Beautified(
+' T'+fComponentName+' = class(TForm)'+LE)
else if NewUnitType=nuDataModule then
NewSource:=NewSource+Beautified(
+' T'+fComponentName+' = class(TDataModule)'+LE)
else if NewUnitType=nuCGIDataModule then
NewSource:=NewSource+Beautified(
+' T'+fComponentName+' = class(TCGIDataModule)'+LE);
NewSource:=NewSource+Beautified(
' private'+LE);
NewSource:=NewSource
+' { private declarations }'+LE;
NewSource:=NewSource+Beautified(
+' public'+LE);
NewSource:=NewSource
+' { public declarations }'+LE;
NewSource:=NewSource+Beautified(
+' end;'+LE
+LE
+'var'+LE
+' '+fComponentName+': T'+fComponentName+';'+LE
+LE
+'implementation'+LE
+LE
+'initialization'+LE);
NewSource:=NewSource
+' {$I '+AResourceFilename+'}'+LE;
end;
end;
NewSource:=NewSource+Beautified(
+LE
+'end.'+LE
+LE);
end else if NewUnitType in [nuCustomProgram] then begin
NewSource:=NewSource+Beautified(
+'program CustomProgram;'+LE
+LE
+'{$mode objfpc}{$H+}'+LE
+LE
+'uses'+LE
+' Classes, SysUtils;'+LE
+LE
+'begin'+LE
+'end.'+LE
+LE);
end;
fSource.Source:=NewSource;
fModified:=true;
end;
function TUnitInfo.GetHasResources:boolean;
begin
Result:=fHasResources or (ComponentName<>'');
end;
function TUnitInfo.GetNextAutoRevertLockedUnit: TUnitInfo;
begin
Result:=fNext[uilAutoRevertLocked];
end;
function TUnitInfo.GetNextLoadedUnit: TUnitInfo;
begin
Result:=fNext[uilLoaded];
end;
function TUnitInfo.GetNextPartOfProject: TUnitInfo;
begin
Result:=fNext[uilPartOfProject];
end;
function TUnitInfo.GetNextUnitWithComponent: TUnitInfo;
begin
Result:=fNext[uilWithComponent];
end;
function TUnitInfo.GetNextUnitWithEditorIndex: TUnitInfo;
begin
Result:=fNext[uilWithEditorIndex];
end;
function TUnitInfo.GetPrevAutoRevertLockedUnit: TUnitInfo;
begin
Result:=fPrev[uilAutoRevertLocked];
end;
function TUnitInfo.GetPrevLoadedUnit: TUnitInfo;
begin
Result:=fPrev[uilLoaded];
end;
function TUnitInfo.GetPrevPartOfProject: TUnitInfo;
begin
Result:=fPrev[uilPartOfProject];
end;
function TUnitInfo.GetPrevUnitWithComponent: TUnitInfo;
begin
Result:=fPrev[uilWithComponent];
end;
function TUnitInfo.GetPrevUnitWithEditorIndex: TUnitInfo;
begin
Result:=fPrev[uilWithEditorIndex];
end;
procedure TUnitInfo.SetBuildFileIfActive(const AValue: boolean);
begin
if FBuildFileIfActive=AValue then exit;
FBuildFileIfActive:=AValue;
Modified:=true;
end;
procedure TUnitInfo.SetEditorIndex(const AValue: integer);
begin
if fEditorIndex=AValue then exit;
fEditorIndex:=AValue;
UpdateList(uilWithEditorIndex,fEditorIndex>=0);
end;
procedure TUnitInfo.SetFileReadOnly(const AValue: Boolean);
begin
if fFileReadOnly=AValue then exit;
fFileReadOnly:=AValue;
if fSource<>nil then
fSource.ReadOnly:=ReadOnly;
end;
procedure TUnitInfo.SetComponent(const AValue: TComponent);
begin
if fComponent=AValue then exit;
fComponent:=AValue;
UpdateList(uilWithComponent,fComponent<>nil);
end;
procedure TUnitInfo.SetIsPartOfProject(const AValue: boolean);
begin
if fIsPartOfProject=AValue then exit;
if Project<>nil then Project.BeginUpdate(true);
fIsPartOfProject:=AValue;
UpdateList(uilPartOfProject,fIsPartOfProject);
if fIsPartOfProject then UpdateUsageCount(uuIsPartOfProject,0);
if Project<>nil then Project.EndUpdate;
end;
{-------------------------------------------------------------------------------
procedure TUnitInfo.SetLoaded(const AValue: Boolean);
Loaded is a flag, that is set, when a unit has finished loading into the
editor. It is saved to the project info file and a loaded unit will be
reloaded, when the project is opened.
-------------------------------------------------------------------------------}
procedure TUnitInfo.SetLoaded(const AValue: Boolean);
begin
if fLoaded=AValue then exit;
fLoaded:=AValue;
if fLoaded then begin
IncreaseAutoRevertLock;
UpdateUsageCount(uuIsLoaded,0);
end else begin
DecreaseAutoRevertLock;
end;
end;
procedure TUnitInfo.SetProject(const AValue: TProject);
var
ListType: TUnitInfoList;
begin
if FProject=AValue then exit;
if FProject<>nil then begin
for ListType:=Low(TUnitInfoList) to High(TUnitInfoList) do
Project.RemoveFromList(Self,ListType);
end;
FProject:=AValue;
if FProject<>nil then begin
if EditorIndex>=0 then Project.AddToList(Self,uilWithEditorIndex);
if Component<>nil then Project.AddToList(Self,uilWithComponent);
if Loaded then Project.AddToList(Self,uilLoaded);
if IsAutoRevertLocked then Project.AddToList(Self,uilAutoRevertLocked);
if IsPartOfProject then Project.AddToList(Self,uilPartOfProject);
end;
end;
procedure TUnitInfo.SetRunFileIfActive(const AValue: boolean);
begin
if FRunFileIfActive=AValue then exit;
FRunFileIfActive:=AValue;
Modified:=true;
end;
{------------------------------------------------------------------------------
TProject Class
------------------------------------------------------------------------------}
{------------------------------------------------------------------------------
TProject Constructor
------------------------------------------------------------------------------}
constructor TProject.Create(TheProjectType: TProjectType);
var PrgUnitInfo: TUnitInfo;
NewSource: TStringList;
NewPrgBuf: TCodeBuffer;
begin
inherited Create;
Assert(False, 'Trace:Project Class Created');
xmlconfig := nil;
fProjectType:=TheProjectType;
fActiveEditorIndexAtStart := -1;
FAutoCreateForms := true;
fBookmarks := TProjectBookmarkList.Create;
fCompilerOptions := TProjectCompilerOptions.Create(Self);
FDefineTemplates:=TProjectDefineTemplates.Create(Self);
FFlags:=DefaultProjectFlags;
fIconPath := '';
fJumpHistory:=TProjectJumpHistory.Create;
fJumpHistory.OnCheckPosition:=@JumpHistoryCheckPosition;
fJumpHistory.OnLoadSaveFilename:=@OnLoadSaveFilename;
fMainUnitID := -1;
fModified := false;
fProjectInfoFile := '';
UpdateProjectDirectory;
fPublishOptions:=TPublishProjectOptions.Create(Self);
fRunParameterOptions:=TRunParamsOptions.Create;
fTargetFileExt := GetDefaultExecutableExt;
fTitle := '';
fUnitList := TList.Create; // list of TUnitInfo
// create program source
NewSource:=TStringList.Create;
case fProjectType of
ptProgram, ptApplication, ptCustomProgram, ptCGIApplication:
begin
NewPrgBuf:=CodeToolBoss.CreateFile(
'project1'+ProjectDefaultExt[fProjectType]);
PrgUnitInfo:=TUnitInfo.Create(NewPrgBuf);
PrgUnitInfo.IsPartOfProject:=true;
PrgUnitInfo.SyntaxHighlighter:=
ExtensionToLazSyntaxHighlighter(ProjectDefaultExt[fProjectType]);
AddUnit(PrgUnitInfo,false);
MainUnitID:=0;
with NewSource do begin
Add('program Project1;');
Add('');
Add('{$mode objfpc}{$H+}');
if fProjectType in [ptApplication] then
Add('{$AppType Gui} // for win32 applications');
Add('');
Add('uses');
case fProjectType of
ptProgram, ptCustomProgram:
Add(' Classes;');
ptApplication:
begin
Add(' Interfaces,');
Add(' Forms;');
end;
ptCGIApplication:
Add(' cgiModules;');
else
Add(' { add your units here };');
end;
Add('');
Add('begin');
case fProjectType of
ptApplication:
begin
Add(' Application.Initialize;');
Add(' Application.Run;');
end;
end;
Add('end.');
Add('');
end;
MainUnitInfo.Source.Assign(NewSource);
end;
end;
NewSource.Free;
end;
{------------------------------------------------------------------------------
TProject Destructor
------------------------------------------------------------------------------}
destructor TProject.Destroy;
begin
Clear;
FreeThenNil(fBookmarks);
FreeThenNil(xmlconfig);
FreeThenNil(fUnitList);
FreeThenNil(fJumpHistory);
FreeThenNil(fPublishOptions);
FreeThenNil(fRunParameterOptions);
FreeThenNil(fCompilerOptions);
FreeThenNil(FDefineTemplates);
inherited Destroy;
end;
{------------------------------------------------------------------------------
TProject WriteProject
------------------------------------------------------------------------------}
function TProject.WriteProject(ProjectWriteFlags: TProjectWriteFlags;
const OverrideProjectInfoFile: string): TModalResult;
var
confPath: String;
Path: String;
procedure SaveFlags;
var f: TProjectFlag;
begin
for f:=Low(TProjectFlag) to High(TProjectFlag) do begin
xmlconfig.SetDeleteValue(Path+'General/Flags/'
+ProjectFlagNames[f]+'/Value', f in Flags,f in DefaultProjectFlags);
end;
end;
procedure UpdateUsageCounts;
var
UnitUsageCount: extended;
DiffTime: TDateTime;
i: Integer;
begin
UnitUsageCount:=0;
if CompareFileNames(confPath,fLastReadLPIFilename)=0 then begin
DiffTime:=Now-fLastReadLPIFileDate;
if DiffTime>0 then begin
UnitUsageCount:= DiffTime*24; // one step every hour
end;
fLastReadLPIFileDate:=Now;
end;
for i:=0 to UnitCount-1 do begin
if Units[i].IsPartOfProject then
Units[i].UpdateUsageCount(uuIsPartOfProject,UnitUsageCount)
else if Units[i].Loaded then
Units[i].UpdateUsageCount(uuIsLoaded,UnitUsageCount)
else
Units[i].UpdateUsageCount(uuNotUsed,UnitUsageCount);
end;
end;
function UnitMustBeSaved(i: integer): boolean;
begin
Result:=false;
if not Units[i].IsPartOfProject then begin
if (pfSaveOnlyProjectUnits in Flags) then exit;
if (pwfSaveOnlyProjectUnits in ProjectWriteFlags) then exit;
if (not Units[i].Loaded) then begin
if (not (pfSaveClosedUnits in Flags)) then exit;
if (pwfDontSaveClosedUnits in ProjectWriteFlags) then exit;
if Units[i].fUsageCount<=0 then exit;
end;
end;
Result:=true;
end;
procedure SaveUnits;
var i, SaveUnitCount: integer;
begin
SaveUnitCount:=0;
for i:=0 to UnitCount-1 do begin
if UnitMustBeSaved(i) then begin
Units[i].SaveToXMLConfig(
xmlconfig,Path+'Units/Unit'+IntToStr(SaveUnitCount)+'/');
inc(SaveUnitCount);
end;
end;
xmlconfig.SetDeleteValue(Path+'Units/Count',SaveUnitCount,0);
end;
var
AText, ACaption: string;
begin
Result := mrCancel;
if OverrideProjectInfoFile<>'' then
confPath := OverrideProjectInfoFile
else
confPath := ProjectInfoFile;
if Assigned(fOnFileBackup) then begin
Result:=fOnFileBackup(confPath,true);
if Result=mrAbort then exit;
end;
confPath:=SetDirSeparators(confPath);
try
xmlconfig := TXMLConfig.CreateClean(confPath);
except
on E: Exception do begin
writeln('ERROR: ',E.Message);
MessageDlg('Write error',
'Unable to write the project info file'#13
+'"'+ProjectInfoFile+'".'#13
+'Error: '+E.Message
,mtError,[mbOk],0);
Result:=mrCancel;
exit;
end;
end;
UpdateUsageCounts;
repeat
try
Path:='ProjectOptions/';
xmlconfig.SetValue(Path+'Version/Value',ProjectInfoFileVersion);
xmlconfig.SetDeleteValue(Path+'General/ProjectType/Value',
ProjectTypeNames[ProjectType],'');
SaveFlags;
xmlconfig.SetDeleteValue(Path+'General/MainUnit/Value', MainUnitID,-1);
xmlconfig.SetDeleteValue(Path+'General/ActiveEditorIndexAtStart/Value'
,ActiveEditorIndexAtStart,-1);
xmlconfig.SetDeleteValue(Path+'General/AutoCreateForms/Value'
,AutoCreateForms,true);
xmlconfig.SetDeleteValue(Path+'General/IconPath/Value',
IconPath,'');
xmlconfig.SetValue(Path+'General/TargetFileExt/Value'
,TargetFileExt);
xmlconfig.SetDeleteValue(Path+'General/Title/Value', Title,'');
if not (pfSaveOnlyProjectUnits in Flags) then begin
fJumpHistory.DeleteInvalidPositions;
fJumpHistory.SaveToXMLConfig(xmlconfig,Path);
end;
SaveUnits;
// Save the compiler options
CompilerOptions.SaveToXMLConfig(XMLConfig,'CompilerOptions/');
// save the Publish Options
PublishOptions.SaveToXMLConfig(xmlconfig,Path+'PublishOptions/');
// save the Run Parameter Options
RunParameterOptions.Save(xmlconfig,Path);
// save dependencies
SavePkgDependencyList(XMLConfig,Path+'RequiredPackages/',
FFirstRequiredDependency,pdlRequires);
if Assigned(OnSaveProjectInfo) then OnSaveProjectInfo(Self,XMLConfig);
xmlconfig.Flush;
Modified:=false;
except
ACaption:='Write error';
AText:='Unable to write to file "'+confPath+'".';
Result:=Application.MessageBox(PChar(ACaption),PChar(AText),MB_ABORTRETRYIGNORE);
if Result=mrIgnore then Result:=mrOk;
if Result=mrAbort then exit;
end;
until Result<>mrRetry;
xmlconfig.Free;
xmlconfig:=nil;
Result := mrOk;
end;
{------------------------------------------------------------------------------
TProject ReadProject
------------------------------------------------------------------------------}
function TProject.ReadProject(const LPIFilename: string): TModalResult;
var
NewUnitInfo: TUnitInfo;
NewUnitCount,i: integer;
FileVersion: Integer;
OldSrcPath: String;
Path: String;
procedure LoadCompilerOptions;
var
CompOptsPath: String;
begin
CompOptsPath:='CompilerOptions/';
if FileVersion<3 then begin
// due to an old bug, the XML path can be 'CompilerOptions/' or ''
if XMLConfig.GetValue('SearchPaths/CompilerPath/Value','')<>'' then
CompOptsPath:=''
else if XMLConfig.GetValue(
'CompilerOptions/SearchPaths/CompilerPath/Value','')<>''
then
CompOptsPath:='CompilerOptions/';
end;
CompilerOptions.LoadFromXMLConfig(xmlconfig,CompOptsPath);
if FileVersion<2 then CompilerOptions.SrcPath:=OldSrcPath;
end;
procedure LoadFlags;
var f: TProjectFlag;
begin
FFlags:=[];
for f:=Low(TProjectFlag) to High(TProjectFlag) do begin
if xmlconfig.GetValue(Path+'General/Flags/'
+ProjectFlagNames[f]+'/Value', f in DefaultProjectFlags)
then
Include(FFlags,f)
else
Exclude(FFlags,f);
end;
end;
begin
Result := mrCancel;
BeginUpdate(true);
try
Clear;
ProjectInfoFile:=LPIFilename;
try
{$IFDEF IDE_MEM_CHECK}CheckHeapWrtMemCnt('TProject.ReadProject A reading lpi');{$ENDIF}
xmlconfig := TXMLConfig.Create(ProjectInfoFile);
fLastReadLPIFilename:=ProjectInfoFile;
fLastReadLPIFileDate:=Now;
{$IFDEF IDE_MEM_CHECK}CheckHeapWrtMemCnt('TProject.ReadProject B done lpi');{$ENDIF}
except
MessageDlg('Unable to read the project info file'#13'"'+ProjectInfoFile+'".'
,mtError,[mbOk],0);
Result:=mrCancel;
exit;
end;
try
Path:='ProjectOptions/';
fPathDelimChanged:=
XMLConfig.GetValue(Path+'PathDelim/Value', '/')<>PathDelim;
{$IFDEF IDE_MEM_CHECK}CheckHeapWrtMemCnt('TProject.ReadProject C reading values');{$ENDIF}
FileVersion:= XMLConfig.GetValue(Path+'Version/Value',0);
ProjectType := ProjectTypeNameToType(xmlconfig.GetValue(
Path+'General/ProjectType/Value', ''));
LoadFlags;
MainUnitID := xmlconfig.GetValue(Path+'General/MainUnit/Value', -1);
ActiveEditorIndexAtStart := xmlconfig.GetValue(
Path+'General/ActiveEditorIndexAtStart/Value', -1);
AutoCreateForms := xmlconfig.GetValue(
Path+'General/AutoCreateForms/Value', true);
IconPath := xmlconfig.GetValue(Path+'General/IconPath/Value', './');
TargetFileExt := xmlconfig.GetValue(
Path+'General/TargetFileExt/Value', GetDefaultExecutableExt);
Title := xmlconfig.GetValue(Path+'General/Title/Value', '');
fJumpHistory.LoadFromXMLConfig(xmlconfig,Path+'');
if FileVersion<2 then
OldSrcPath := xmlconfig.GetValue(Path+'General/SrcPath/Value','');
{$IFDEF IDE_MEM_CHECK}CheckHeapWrtMemCnt('TProject.ReadProject D reading units');{$ENDIF}
NewUnitCount:=xmlconfig.GetValue(Path+'Units/Count',0);
for i := 0 to NewUnitCount - 1 do begin
NewUnitInfo:=TUnitInfo.Create(nil);
AddUnit(NewUnitInfo,false);
NewUnitInfo.LoadFromXMLConfig(
xmlconfig,Path+'Units/Unit'+IntToStr(i)+'/');
end;
{$IFDEF IDE_MEM_CHECK}CheckHeapWrtMemCnt('TProject.ReadProject E reading comp sets');{$ENDIF}
// Load the compiler options
LoadCompilerOptions;
// load the Publish Options
PublishOptions.LoadFromXMLConfig(xmlconfig,
Path+'PublishOptions/',fPathDelimChanged);
// load the Run Parameter Options
RunParameterOptions.Load(xmlconfig,Path,fPathDelimChanged);
{$IFDEF IDE_MEM_CHECK}CheckHeapWrtMemCnt('TProject.ReadProject update ct boss');{$ENDIF}
CodeToolBoss.GlobalValues.Variables[ExternalMacroStart+'ProjPath']:=
ProjectDirectory;
CodeToolBoss.DefineTree.ClearCache;
// load the dependencies
LoadPkgDependencyList(XMLConfig,Path+'RequiredPackages/',
FFirstRequiredDependency,pdlRequires,Self,true);
if Assigned(OnLoadProjectInfo) then OnLoadProjectInfo(Self,XMLConfig);
finally
{$IFDEF IDE_MEM_CHECK}CheckHeapWrtMemCnt('TProject.ReadProject freeing xml');{$ENDIF}
fPathDelimChanged:=false;
xmlconfig.Free;
xmlconfig:=nil;
end;
finally
EndUpdate;
end;
{$IFDEF IDE_MEM_CHECK}CheckHeapWrtMemCnt('TProject.ReadProject END');{$ENDIF}
Result := mrOk;
end;
{------------------------------------------------------------------------------
TProject AddUnit
------------------------------------------------------------------------------}
procedure TProject.AddUnit(AnUnit: TUnitInfo; AddToProjectFile:boolean);
var
ShortUnitName:string;
NewIndex: integer;
begin
if (AnUnit = nil) then exit;
BeginUpdate(true);
NewIndex:=UnitCount;
fUnitList.Add(AnUnit);
AnUnit.Project:=Self;
AnUnit.OnFileBackup:=@OnUnitFileBackup;
AnUnit.OnLoadSaveFilename:=@OnLoadSaveFilename;
AnUnit.OnUnitNameChange:=@OnUnitNameChange;
// check if this is the new Main Unit
if MainUnitID=NewIndex then
MainUnitInfo.IncreaseAutoRevertLock;
if AddToProjectFile and (MainUnitID>=0) and (MainUnitID<>NewIndex) then begin
// add unit to uses section
ShortUnitName:=AnUnit.UnitName;
if (ShortUnitName<>'') and (not UnitIsUsed(ShortUnitName)) then
CodeToolBoss.AddUnitToMainUsesSection(MainUnitInfo.Source,
ShortUnitName,'');
end;
EndUpdate;
Modified:=true;
end;
{------------------------------------------------------------------------------
TProject RemoveUnit
------------------------------------------------------------------------------}
procedure TProject.RemoveUnit(Index: integer);
var
OldUnitInfo: TUnitInfo;
begin
if (Index<0) or (Index>=UnitCount) then begin
raise Exception.Create('ERROR: TProject.RemoveUnit index out of bounds');
end;
if (Index=MainUnitID) then begin
raise Exception.Create('ERROR: TProject.RemoveUnit index = MainUnit');
end;
BeginUpdate(true);
OldUnitInfo:=Units[Index];
Modified:=true;
if (MainUnitID>=0) then begin
// remove unit from uses section and from createforms in program file
if (OldUnitInfo.IsPartOfProject) then begin
if (OldUnitInfo.UnitName<>'') then
CodeToolBoss.RemoveUnitFromAllUsesSections(Units[MainUnitID].Source,
OldUnitInfo.UnitName);
if (OldUnitInfo.ComponentName<>'') then
CodeToolBoss.RemoveCreateFormStatement(Units[MainUnitID].Source,
OldUnitInfo.ComponentName);
end;
end;
// delete bookmarks of this unit
if OldUnitInfo.EditorIndex>=0 then
Bookmarks.DeleteAllWithEditorIndex(OldUnitInfo.EditorIndex);
// adjust MainUnit
if MainUnitID>=Index then dec(fMainUnitID);
// delete unitinfo instance
OldUnitInfo.Free;
fUnitList.Delete(Index);
EndUpdate;
end;
{------------------------------------------------------------------------------
TProject Clear
------------------------------------------------------------------------------}
procedure TProject.Clear;
var i:integer;
begin
BeginUpdate(true);
FreeThenNil(xmlconfig);
// break and free removed dependencies
while FFirstRemovedDependency<>nil do
DeleteRemovedDependency(FFirstRemovedDependency);
// break and free required dependencies
while FFirstRequiredDependency<>nil do
DeleteRequiredDependency(FFirstRequiredDependency);
// delete files
for i:=0 to UnitCount-1 do Units[i].Free;
fUnitList.Clear;
fRunParameterOptions.Clear;
fActiveEditorIndexAtStart := -1;
fBookmarks.Clear;
fCompilerOptions.Clear;
FDefineTemplates.Clear;
fIconPath := '';
fJumpHistory.Clear;
fMainUnitID := -1;
fModified := false;
fProjectInfoFile := '';
UpdateProjectDirectory;
fPublishOptions.Clear;
fTargetFileExt := GetDefaultExecutableExt;
fTitle := '';
EndUpdate;
end;
procedure TProject.BeginUpdate(Change: boolean);
begin
inc(FUpdateLock);
FDefineTemplates.BeginUpdate;
if FUpdateLock=1 then begin
fChanged:=Change;
if Assigned(OnBeginUpdate) then OnBeginUpdate(Self);
end else
fChanged:=fChanged or Change;
end;
procedure TProject.EndUpdate;
begin
if FUpdateLock<=0 then RaiseException('TProject.EndUpdate');
dec(FUpdateLock);
FDefineTemplates.EndUpdate;
if FUpdateLock=0 then begin
if Assigned(OnEndUpdate) then OnEndUpdate(Self,fChanged);
end;
end;
function TProject.GetUnits(Index:integer):TUnitInfo;
begin
Result:=TUnitInfo(fUnitList[Index]);
end;
procedure TProject.SetFlags(const AValue: TProjectFlags);
begin
FFlags:=AValue;
end;
procedure TProject.SetMainUnitID(const AValue: Integer);
begin
if fMainUnitID=AValue then exit;
if (fMainUnitID>=0) and (fMainUnitID<UnitCount) then begin
MainUnitInfo.DecreaseAutoRevertLock;
end;
fMainUnitID:=AValue;
if (fMainUnitID>=0) and (fMainUnitID<UnitCount) then begin
MainUnitInfo.IncreaseAutoRevertLock;
end;
end;
procedure TProject.SetModified(const AValue: boolean);
begin
if AValue=Modified then exit;
fModified:=AValue;
if not fModified then PublishOptions.Modified:=false;
end;
procedure TProject.SetUnits(Index:integer; AUnitInfo: TUnitInfo);
begin
if AUnitInfo<>TUnitInfo(fUnitList[Index]) then begin
fUnitList[Index]:=AUnitInfo;
Modified:=true;
if AUnitInfo<>nil then AUnitInfo.Project:=Self;
end;
end;
function TProject.UnitCount:integer;
begin
Result:=fUnitList.Count;
end;
function TProject.NewUniqueUnitName(NewUnitType:TNewUnitType):string;
function ExpandedUnitname(const AnUnitName:string):string;
begin
Result:=uppercase(ExtractFileNameOnly(AnUnitName));
end;
function UnitNameExists(const AnUnitName:string):boolean;
var i:integer;
ExpName:string;
begin
Result:=true;
ExpName:=ExpandedUnitName(AnUnitName);
if ExtractFileNameOnly(fProjectInfoFile)=Expname then exit;
for i:=0 to UnitCount-1 do
if (Units[i].IsPartOfProject)
and (ExpandedUnitName(Units[i].FileName)=ExpName) then
exit;
Result:=false;
end;
// NewUniqueUnitName(NewUnitType:TNewUnitType)
var u:integer;
Prefix: string;
begin
u:=1;
case NewUnitType of
nuForm,nuUnit,nuDataModule,nuCGIDataModule: Prefix:='unit';
else Prefix:='text'
end;
while (UnitNameExists(Prefix+IntToStr(u))) do inc(u);
Result:=Prefix+IntToStr(u);
end;
function TProject.NewUniqueComponentName(NewUnitType:TNewUnitType):string;
function FormComponentExists(const AComponentName: string): boolean;
var i: integer;
begin
Result:=true;
for i:=0 to UnitCount-1 do begin
if (Units[i].Component<>nil) then begin
if AnsiCompareText(Units[i].Component.Name,AComponentName)=0 then exit;
if AnsiCompareText(Units[i].Component.ClassName,'T'+AComponentName)=0
then exit;
end else if (Units[i].ComponentName<>'')
and ((Units[i].IsPartOfProject) or (Units[i].Loaded)) then begin
if AnsiCompareText(Units[i].ComponentName,AComponentName)=0 then exit;
end;
end;
Result:=false;
end;
// NewUniqueComponentName(NewUnitType:TNewUnitType)
var i: integer;
Prefix: string;
begin
i:=1;
case NewUnitType of
nuForm, nuUnit: Prefix:='Form';
nuDataModule: Prefix:='DataModule';
nuCGIDataModule: Prefix:='CGIDataModule';
else
Prefix:='form';
end;
while (FormComponentExists(Prefix+IntToStr(i))) do inc(i);
Result:=Prefix+IntToStr(i);
end;
function TProject.AddCreateFormToProjectFile(
const AClassName, AName: string):boolean;
begin
Result:=CodeToolBoss.AddCreateFormStatement(MainUnitInfo.Source,
AClassName,AName);
if Result then Modified:=true;
end;
function TProject.RemoveCreateFormFromProjectFile(
const AClassName,AName:string):boolean;
begin
Result:=CodeToolBoss.RemoveCreateFormStatement(MainUnitInfo.Source,
AName);
if Result then Modified:=true;
end;
function TProject.FormIsCreatedInProjectFile(
const AClassname,AName:string):boolean;
var p: integer;
begin
Result:=(CodeToolBoss.FindCreateFormStatement(MainUnitInfo.Source,
1,AClassName,AName,p)=0);
end;
function TProject.IndexOfUnitWithName(const AnUnitName:string;
OnlyProjectUnits:boolean; IgnoreUnit: TUnitInfo):integer;
begin
Result:=UnitCount-1;
while (Result>=0) do begin
if ((OnlyProjectUnits and Units[Result].IsPartOfProject)
or (not OnlyProjectUnits))
and (IgnoreUnit<>Units[Result]) then begin
if (AnsiCompareText(Units[Result].UnitName,AnUnitName)=0) then
exit;
end;
dec(Result);
end;
end;
function TProject.IndexOfUnitWithComponent(AComponent: TComponent;
OnlyProjectUnits:boolean; IgnoreUnit: TUnitInfo):integer;
begin
Result:=UnitCount-1;
while (Result>=0) do begin
if (OnlyProjectUnits and Units[Result].IsPartOfProject)
or (not OnlyProjectUnits)
and (IgnoreUnit<>Units[Result]) then begin
if Units[Result].Component=AComponent then
exit;
end;
dec(Result);
end;
end;
function TProject.IndexOfUnitWithComponentName(const AComponentName: string;
OnlyProjectUnits: boolean; IgnoreUnit: TUnitInfo): integer;
begin
Result:=UnitCount-1;
while (Result>=0) do begin
if ((OnlyProjectUnits and Units[Result].IsPartOfProject)
or (not OnlyProjectUnits))
and (IgnoreUnit<>Units[Result]) then begin
if (AnsiCompareText(Units[Result].ComponentName,AComponentName)=0)
or ((Units[Result].Component<>nil)
and (AnsiCompareText(Units[Result].Component.Name,AComponentName)=0))
then
exit;
end;
dec(Result);
end;
end;
function TProject.UnitWithEditorIndex(Index:integer):TUnitInfo;
begin
Result:=fFirst[uilWithEditorIndex];
while (Result<>nil) and (Result.EditorIndex<>Index) do begin
Result:=Result.fNext[uilWithEditorIndex];
end;
end;
function TProject.UnitIsUsed(const ShortUnitName:string):boolean;
var NamePos, InPos: integer;
begin
Result:=CodeToolBoss.FindUnitInAllUsesSections(MainUnitInfo.Source,
ShortUnitName,NamePos,InPos);
end;
function TProject.GetResourceFile(AnUnitInfo: TUnitInfo;
Index:integer): TCodeBuffer;
var i, LinkIndex: integer;
begin
LinkIndex:=-1;
i:=0;
Result:=nil;
while (i<Index) do begin
inc(i);
Result:=CodeToolBoss.FindNextResourceFile(AnUnitInfo.Source,LinkIndex);
end;
end;
function TProject.SearchFile(
const Filename,SearchPaths,InitialDir:string):string;
var StartPos,EndPos:integer;
CurPath: string;
OldDir: string;
begin
OldDir:=GetCurrentDir;
SetCurrentDir(ExtractFilePath(InitialDir));
try
StartPos:=1;
while StartPos<=length(SearchPaths) do begin
EndPos:=Startpos;
while (EndPos<=length(SearchPaths)) and (SearchPaths[EndPos]<>';') do
inc(EndPos);
CurPath:=copy(SearchPaths,Startpos,EndPos-StartPos);
if CurPath<>'' then begin
if CurPath[length(CurPath)]<>PathDelim then
CurPath:=CurPath+PathDelim;
Result:=CurPath+Filename;
if FileExists(Result) then exit;
end;
StartPos:=EndPos+1;
end;
finally
SetCurrentDir(OldDir);
end;
Result:='';
end;
procedure TProject.ShortenFilename(var AFilename: string);
begin
OnLoadSaveFilename(AFilename,false);
end;
procedure TProject.LongenFilename(var AFilename: string);
begin
OnLoadSaveFilename(AFilename,true);
end;
function TProject.GetMainResourceFilename(AnUnitInfo: TUnitInfo):string;
var CodeBuf: TCodeBuffer;
begin
CodeBuf:=GetResourceFile(AnUnitInfo,1);
if CodeBuf=nil then begin
if AnUnitInfo.Filename='' then exit;
Result:=ChangeFileExt(AnUnitInfo.Filename,ResourceFileExt);
exit;
end else
Result:=CodeBuf.Filename;
end;
function TProject.IsVirtual: boolean;
begin
Result:=(MainUnitID>=0) and MainUnitInfo.IsVirtual;
end;
function TProject.IndexOf(AUnitInfo: TUnitInfo):integer;
begin
Result:=UnitCount-1;
while (Result>=0) and (Units[Result]<>AUnitInfo) do dec(Result);
end;
procedure TProject.CloseEditorIndex(EditorIndex:integer);
var i:integer;
AnUnitInfo, NextUnitInfo: TUnitInfo;
begin
AnUnitInfo:=fFirst[uilWithEditorIndex];
while AnUnitInfo<>nil do begin
NextUnitInfo:=AnUnitInfo.fNext[uilWithEditorIndex];
if AnUnitInfo.EditorIndex=EditorIndex then
AnUnitInfo.EditorIndex:=-1
else if AnUnitInfo.EditorIndex>EditorIndex then
AnUnitInfo.EditorIndex:=AnUnitInfo.EditorIndex-1;
AnUnitInfo:=NextUnitInfo;
end;
i:=Bookmarks.Count-1;
while (i>=0) do begin
if (Bookmarks[i].EditorIndex=EditorIndex) then
Bookmarks.Delete(i)
else
Bookmarks[i].EditorIndex:=Bookmarks[i].EditorIndex-1;
dec(i);
end;
Modified:=true;
end;
procedure TProject.InsertEditorIndex(EditorIndex:integer);
function MoveIndex(OldIndex: integer): integer;
begin
Result:=OldIndex;
if OldIndex>=EditorIndex then
inc(Result);
end;
var i:integer;
AnUnitInfo: TUnitInfo;
begin
// move all editor index of units:
AnUnitInfo:=fFirst[uilWithEditorIndex];
while AnUnitInfo<>nil do begin
AnUnitInfo.EditorIndex:=MoveIndex(AnUnitInfo.EditorIndex);
AnUnitInfo:=AnUnitInfo.fNext[uilWithEditorIndex];
end;
// move bookmarks
i:=Bookmarks.Count-1;
while (i>=0) do begin
Bookmarks[i].EditorIndex:=MoveIndex(Bookmarks[i].EditorIndex);
dec(i);
end;
Modified:=true;
end;
procedure TProject.MoveEditorIndex(OldEditorIndex, NewEditorIndex: integer);
function MoveIndex(OldIndex: integer): integer;
begin
Result:=OldIndex;
if OldIndex=OldEditorIndex then
// this is the moving index
Result:=NewEditorIndex
else if OldIndex>OldEditorIndex then begin
// right of OldPageIndex ...
if OldIndex<=NewEditorIndex then
// .. and left of NewEditorIndex
// -> move left
Dec(Result);
end else begin
// left of OldPageIndex ...
if OldIndex>=NewEditorIndex then
// .. and right of NewEditorIndex
// -> move right
Inc(Result);
end;
end;
var
i:integer;
AnUnitInfo: TUnitInfo;
begin
if OldEditorIndex=NewEditorIndex then exit;
// move all editor index of units:
AnUnitInfo:=fFirst[uilWithEditorIndex];
while AnUnitInfo<>nil do begin
AnUnitInfo.EditorIndex:=MoveIndex(AnUnitInfo.EditorIndex);
AnUnitInfo:=AnUnitInfo.fNext[uilWithEditorIndex];
end;
// move bookmarks
i:=Bookmarks.Count-1;
while (i>=0) do begin
Bookmarks[i].EditorIndex:=MoveIndex(Bookmarks[i].EditorIndex);
dec(i);
end;
Modified:=true;
end;
procedure TProject.AddToOrRemoveFromEditorWithIndexList(AnUnitInfo: TUnitInfo);
begin
if AnUnitInfo.EditorIndex<0 then begin
RemoveFromList(AnUnitInfo,uilWithEditorIndex);
end else begin
AddToList(AnUnitInfo,uilWithEditorIndex);
end;
end;
procedure TProject.AddToOrRemoveFromComponentList(AnUnitInfo: TUnitInfo);
begin
if AnUnitInfo.Component=nil then begin
RemoveFromList(AnUnitInfo,uilWithComponent);
end else begin
AddToList(AnUnitInfo,uilWithComponent);
end;
end;
procedure TProject.AddToOrRemoveFromLoadedList(AnUnitInfo: TUnitInfo);
begin
if not AnUnitInfo.Loaded then begin
RemoveFromList(AnUnitInfo,uilLoaded);
end else begin
AddToList(AnUnitInfo,uilLoaded);
end;
end;
procedure TProject.AddToOrRemoveFromAutoRevertLockedList(AnUnitInfo: TUnitInfo);
begin
if not AnUnitInfo.IsAutoRevertLocked then begin
RemoveFromList(AnUnitInfo,uilAutoRevertLocked);
end else begin
AddToList(AnUnitInfo,uilAutoRevertLocked);
end;
end;
procedure TProject.AddToOrRemoveFromPartOfProjectList(AnUnitInfo: TUnitInfo);
begin
if not AnUnitInfo.IsPartOfProject then begin
RemoveFromList(AnUnitInfo,uilPartOfProject);
end else begin
AddToList(AnUnitInfo,uilPartOfProject);
end;
end;
function TProject.GetTargetFilename: string;
begin
Result:=fCompilerOptions.TargetFilename;
end;
procedure TProject.SetTargetFilename(const NewTargetFilename: string);
begin
fCompilerOptions.TargetFilename:=NewTargetFilename;
end;
function TProject.GetMainFilename: String;
begin
if MainUnitID>=0 then Result:=MainUnitInfo.Filename
else Result:='';
end;
function TProject.GetFirstPartOfProject: TUnitInfo;
begin
Result:=FFirst[uilPartOfProject];
end;
function TProject.GetFirstLoadedUnit: TUnitInfo;
begin
Result:=fFirst[uilLoaded];
end;
function TProject.GetFirstAutoRevertLockedUnit: TUnitInfo;
begin
Result:=fFirst[uilAutoRevertLocked];
end;
function TProject.GetFirstUnitWithComponent: TUnitInfo;
begin
Result:=fFirst[uilWithComponent];
end;
function TProject.GetFirstUnitWithEditorIndex: TUnitInfo;
begin
Result:=fFirst[uilWithEditorIndex];
end;
function TProject.GetMainUnitInfo: TUnitInfo;
begin
if (MainUnitID>=0) and (MainUnitID<UnitCount) then
Result:=Units[MainUnitID]
else
Result:=nil;
end;
function TProject.GetProjectInfoFile:string;
begin
Result:=fProjectInfoFile;
end;
procedure TProject.SetProjectInfoFile(const NewFilename:string);
var
NewProjectInfoFile: String;
begin
NewProjectInfoFile:=TrimFilename(NewFilename);
if NewProjectInfoFile='' then exit;
DoDirSeparators(NewProjectInfoFile);
if (AnsiCompareText(fTitle,ExtractFileNameOnly(fProjectInfoFile))=0)
or (fProjectInfoFile='') or (fTitle='') then begin
fTitle:=ExtractFileNameOnly(NewProjectInfoFile);
end;
fProjectInfoFile:=NewProjectInfoFile;
UpdateProjectDirectory;
Modified:=true;
end;
function TProject.OnUnitFileBackup(const Filename:string;
IsPartOfProject:boolean):TModalResult;
begin
if Assigned(fOnFileBackup) then
Result:=fOnFileBackup(Filename,IsPartOfProject)
else
Result:=mrOk;
end;
procedure TProject.OnLoadSaveFilename(var AFilename: string; Load:boolean);
var ProjectPath:string;
begin
if AFileName='' then exit;
ProjectPath:=ProjectDirectory;
if ProjectPath='' then ProjectPath:=GetCurrentDir;
if fPathDelimChanged then
DoDirSeparators(AFilename);
AFilename:=TrimFilename(AFilename);
if Load then begin
// make filename absolute
if (AFilename<>'') and (not FilenameIsAbsolute(AFilename)) then
AFilename:=TrimFilename(ProjectPath+AFilename);
end else begin
// try making filename relative to project file
if (AFilename<>'') and FilenameIsAbsolute(AFilename)
and FileIsInPath(AFilename,ProjectPath) then
AFilename:=CreateRelativePath(AFilename,ProjectPath);
end;
end;
function TProject.RemoveProjectPathFromFilename(
const AFilename: string): string;
var ProjectPath:string;
begin
ProjectPath:=ProjectDirectory;
if ProjectPath='' then ProjectPath:=GetCurrentDir;
Result:=AFilename;
DoDirSeparators(Result);
// try making filename relative to project file
if FilenameIsAbsolute(Result)
and (CompareFileNames(copy(Result,1,length(ProjectPath)),ProjectPath)=0)
then
Result:=copy(Result,length(ProjectPath)+1,
length(Result)-length(ProjectPath));
end;
function TProject.FileIsInProjectDir(const AFilename: string): boolean;
var ProjectDir, FilePath: string;
begin
if FilenameIsAbsolute(AFilename) then begin
if (not IsVirtual) then begin
ProjectDir:=ProjectDirectory;
FilePath:=LeftStr(AFilename,length(ProjectDir));
Result:=(CompareFileNames(ProjectDir,FilePath)=0);
end else
Result:=false;
end else
Result:=true;
end;
procedure TProject.GetVirtualDefines(DefTree: TDefineTree;
DirDef: TDirectoryDefines);
procedure ExtendPath(const AVariable, APath: string);
var
TempValue: string;
begin
if APath<>'' then begin
DefTree.ReadValue(DirDef,APath+';','',TempValue);
DirDef.Values.Prepend(AVariable,TempValue);
end;
end;
begin
if (not IsVirtual) then exit;
ExtendPath(UnitPathMacroName,CompilerOptions.OtherUnitFiles);
ExtendPath(IncludePathMacroName,CompilerOptions.IncludeFiles);
ExtendPath(SrcPathMacroName,CompilerOptions.SrcPath);
end;
procedure TProject.GetUnitsChangedOnDisk(var AnUnitList: TList);
var
AnUnitInfo: TUnitInfo;
begin
AnUnitList:=nil;
AnUnitInfo:=fFirst[uilAutoRevertLocked];
while (AnUnitInfo<>nil) do begin
if AnUnitInfo.ChangedOnDisk(false) then begin
if AnUnitList=nil then
AnUnitList:=TList.Create;
AnUnitList.Add(AnUnitInfo);
end;
AnUnitInfo:=AnUnitInfo.fNext[uilAutoRevertLocked];
end;
end;
procedure TProject.SetBookmark(AnUnitInfo: TUnitInfo; X, Y, ID: integer);
begin
if AnUnitInfo.EditorIndex>=0 then
Bookmarks.Add(X,Y,AnUnitInfo.EditorIndex,ID);
AnUnitInfo.Bookmarks.Add(X,Y,ID);
end;
procedure TProject.MergeBookmarks(AnUnitInfo: TUnitInfo);
// merge the bookmarks of the unit with the bookmarks in the source editor
var
i: Integer;
UnitMark: TFileBookmark;
ProjectMark: TProjectBookmark;
begin
if AnUnitInfo.EditorIndex<0 then exit;
for i:=0 to AnUnitInfo.Bookmarks.Count-1 do begin
UnitMark:=AnUnitInfo.Bookmarks[i];
ProjectMark:=Bookmarks.BookmarkWithIndex(UnitMark.ID);
// merge the bookmark into the currently existing bookmarks, if the ID is
// free
//writeln('TProject.MergeBookmarks ',AnUnitInfo.Filename,' Y=',UnitMark.Y);
if (ProjectMark=nil) then
Bookmarks.Add(UnitMark.X,UnitMark.Y,AnUnitInfo.EditorIndex,UnitMark.ID);
end;
end;
function TProject.FindDependencyByName(const PackageName: string
): TPkgDependency;
begin
Result:=FindDependencyByNameInList(FFirstRequiredDependency,pdlRequires,
PackageName);
end;
function TProject.RequiredDepByIndex(Index: integer): TPkgDependency;
begin
Result:=GetDependencyWithIndex(FFirstRequiredDependency,pdlRequires,Index);
end;
function TProject.RemovedDepByIndex(Index: integer): TPkgDependency;
begin
Result:=GetDependencyWithIndex(FFirstRemovedDependency,pdlRequires,Index);
end;
procedure TProject.AddRequiredDependency(Dependency: TPkgDependency);
begin
BeginUpdate(true);
Dependency.AddToList(FFirstRequiredDependency,pdlRequires);
Dependency.Owner:=Self;
Dependency.HoldPackage:=true;
Modified:=true;
EndUpdate;
end;
procedure TProject.RemoveRequiredDependency(Dependency: TPkgDependency);
begin
BeginUpdate(true);
Dependency.RemoveFromList(FFirstRequiredDependency,pdlRequires);
Dependency.RequiredPackage:=nil;
Dependency.AddToList(FFirstRemovedDependency,pdlRequires);
Dependency.Removed:=true;
Modified:=true;
EndUpdate;
end;
procedure TProject.DeleteRequiredDependency(Dependency: TPkgDependency);
begin
BeginUpdate(true);
Dependency.RequiredPackage:=nil;
Dependency.RemoveFromList(FFirstRequiredDependency,pdlRequires);
Dependency.Free;
EndUpdate;
end;
procedure TProject.DeleteRemovedDependency(Dependency: TPkgDependency);
begin
BeginUpdate(true);
Dependency.RequiredPackage:=nil;
Dependency.RemoveFromList(FFirstRemovedDependency,pdlRequires);
Dependency.Free;
EndUpdate;
end;
procedure TProject.RemoveRemovedDependency(Dependency: TPkgDependency);
begin
BeginUpdate(true);
Dependency.RemoveFromList(FFirstRemovedDependency,pdlRequires);
Dependency.Removed:=false;
EndUpdate;
end;
procedure TProject.ReaddRemovedDependency(Dependency: TPkgDependency);
begin
BeginUpdate(true);
RemoveRemovedDependency(Dependency);
AddRequiredDependency(Dependency);
EndUpdate;
end;
procedure TProject.MoveRequiredDependencyUp(Dependency: TPkgDependency);
begin
if Dependency.PrevRequiresDependency=nil then exit;
BeginUpdate(true);
Dependency.MoveUpInList(FFirstRequiredDependency,pdlRequires);
EndUpdate;
end;
procedure TProject.MoveRequiredDependencyDown(Dependency: TPkgDependency);
begin
if Dependency.NextRequiresDependency=nil then exit;
BeginUpdate(true);
Dependency.MoveDownInList(FFirstRequiredDependency,pdlRequires);
EndUpdate;
end;
function TProject.Requires(APackage: TLazPackage): boolean;
begin
Result:=FindCompatibleDependencyInList(FFirstRequiredDependency,pdlRequires,
APackage)<>nil;
end;
procedure TProject.GetAllRequiredPackages(var List: TList);
begin
if Assigned(OnGetAllRequiredPackages) then
OnGetAllRequiredPackages(FirstRequiredDependency,List);
end;
procedure TProject.OnUnitNameChange(AnUnitInfo: TUnitInfo;
const OldUnitName, NewUnitName: string; CheckIfAllowed: boolean;
var Allowed: boolean);
var i:integer;
begin
if AnUnitInfo.IsPartOfProject then begin
if CheckIfAllowed then begin
// check if no other project unit has this name
for i:=0 to UnitCount-1 do begin
if (Units[i].IsPartOfProject)
and (Units[i]<>AnUnitInfo) and (Units[i].UnitName<>'')
and (lowercase(Units[i].UnitName)=lowercase(NewUnitName)) then begin
Allowed:=false;
exit;
end;
end;
end;
if (OldUnitName<>'')
and (ProjectType in [ptProgram, ptApplication, ptCGIApplication]) then
begin
// rename unit in program uses section
CodeToolBoss.RenameUsedUnit(MainUnitInfo.Source
,OldUnitName,NewUnitName,'');
end;
end;
end;
function TProject.JumpHistoryCheckPosition(
APosition:TProjectJumpHistoryPosition): boolean;
var i: integer;
begin
i:=IndexOfFilename(APosition.Filename);
Result:=(i>=0) and (Units[i].EditorIndex>=0);
end;
function TProject.SomethingModified: boolean;
var i: integer;
begin
Result:=Modified;
for i:=0 to UnitCount-1 do Result:=Result or Units[i].Modified;
Result:=Result or CompilerOptions.Modified;
end;
procedure TProject.MainSourceFilenameChanged;
begin
end;
Function TProject.UnitWithComponent(AComponent: TComponent) : TUnitInfo;
begin
Result:=fFirst[uilWithComponent];
while (Result<>nil) and (Result.Component<>AComponent) do
Result:=Result.fNext[uilWithComponent];
end;
function TProject.UnitInfoWithFilename(const AFilename: string): TUnitInfo;
var
i: Integer;
begin
i:=IndexOfFilename(AFilename);
if i>=0 then
Result:=Units[i]
else
Result:=nil;
end;
function TProject.UnitWithUnitname(const AnUnitname: string): TUnitInfo;
var
i: Integer;
begin
i:=IndexOfUnitWithName(AnUnitName,true,nil);
if i>=0 then
Result:=Units[i]
else
Result:=nil;
end;
function TProject.IndexOfFilename(const AFilename: string): integer;
begin
Result:=UnitCount-1;
while (Result>=0) do begin
if CompareFilenames(AFilename,Units[Result].Filename)=0 then exit;
dec(Result);
end;
end;
function TProject.IndexOfFilename(const AFilename: string;
SearchFlags: TProjectFileSearchFlags): integer;
var
BaseFilename: String;
CurBaseFilename: String;
begin
BaseFilename:=AFilename;
if pfsfResolveFileLinks in SearchFlags then
BaseFilename:=ReadAllLinks(AFilename,false);
Result:=UnitCount-1;
while (Result>=0) do begin
if (pfsfOnlyEditorFiles in SearchFlags)
and (Units[Result].EditorIndex<0) then begin
dec(Result);
continue;
end;
CurBaseFilename:=Units[Result].Filename;
if pfsfResolveFileLinks in SearchFlags then
CurBaseFilename:=ReadAllLinks(CurBaseFilename,false);
if CompareFilenames(BaseFilename,CurBaseFilename)=0 then exit;
dec(Result);
end;
end;
function TProject.ProjectUnitWithFilename(const AFilename: string): TUnitInfo;
begin
Result:=fFirst[uilPartOfProject];
while Result<>nil do begin
if CompareFileNames(AFilename,Result.Filename)=0 then exit;
Result:=Result.fNext[uilPartOfProject];
end;
end;
function TProject.ProjectUnitWithUnitname(const AnUnitName: string): TUnitInfo;
begin
Result:=fFirst[uilPartOfProject];
while Result<>nil do begin
if AnsiCompareText(AnUnitName,Result.UnitName)=0 then exit;
Result:=Result.fNext[uilPartOfProject];
end;
end;
procedure TProject.UpdateProjectDirectory;
begin
fProjectDirectory:=ExtractFilePath(fProjectInfoFile);
CompilerOptions.BaseDirectory:=fProjectDirectory;
end;
procedure TProject.AddToList(AnUnitInfo: TUnitInfo; ListType: TUnitInfoList);
begin
// add to list if AnUnitInfo is not in list
if (fFirst[ListType]<>AnUnitInfo)
and (AnUnitInfo.fNext[ListType]=nil)
and (AnUnitInfo.fPrev[ListType]=nil) then begin
AnUnitInfo.fNext[ListType]:=fFirst[ListType];
AnUnitInfo.fPrev[ListType]:=nil;
fFirst[ListType]:=AnUnitInfo;
if AnUnitInfo.fNext[ListType]<>nil then
AnUnitInfo.fNext[ListType].fPrev[ListType]:=AnUnitInfo;
end;
end;
procedure TProject.RemoveFromList(AnUnitInfo: TUnitInfo;
ListType: TUnitInfoList);
begin
// remove from list if AnUnitInfo is in list
if fFirst[ListType]=AnUnitInfo then
fFirst[ListType]:=AnUnitInfo.fNext[ListType];
if AnUnitInfo.fNext[ListType]<>nil then
AnUnitInfo.fNext[ListType].fPrev[ListType]:=
AnUnitInfo.fPrev[ListType];
if AnUnitInfo.fPrev[ListType]<>nil then
AnUnitInfo.fPrev[ListType].fNext[ListType]:=
AnUnitInfo.fNext[ListType];
AnUnitInfo.fNext[ListType]:=nil;
AnUnitInfo.fPrev[ListType]:=nil;
end;
{ TProjectCompilerOptions }
constructor TProjectCompilerOptions.Create(TheProject: TProject);
begin
inherited Create(TheProject);
fOwnerProject:=TheProject;
end;
function TProjectCompilerOptions.GetOwnerName: string;
begin
Result:=OwnerProject.Title;
if Result='' then Result:=ExtractFilename(OwnerProject.ProjectInfoFile);
end;
function TProjectCompilerOptions.GetDefaultMainSourceFileName: string;
var
MainUnitInfo: TUnitInfo;
begin
MainUnitInfo:=FOwnerProject.MainUNitInfo;
if (MainUnitInfo<>nil) then
Result:=ExtractFileName(MainUnitInfo.Filename);
if Result='' then
Result:=inherited GetDefaultMainSourceFileName;
end;
procedure TProjectCompilerOptions.GetInheritedCompilerOptions(
var OptionsList: TList);
var
PkgList: TList;
begin
PkgList:=nil;
OwnerProject.GetAllRequiredPackages(PkgList);
OptionsList:=GetUsageOptionsList(PkgList);
PkgList.Free;
end;
{ TProjectDefineTemplates }
constructor TProjectDefineTemplates.Create(OwnerProject: TProject);
begin
inherited Create;
FProject:=OwnerProject;
end;
destructor TProjectDefineTemplates.Destroy;
begin
Clear;
inherited Destroy;
end;
procedure TProjectDefineTemplates.Clear;
begin
if FMain<>nil then begin
if CodeToolBoss<>nil then
CodeToolBoss.DefineTree.RemoveDefineTemplate(FMain);
FMain:=nil;
FProjectDir:=nil;
FFlags:=FFlags+[ptfFlagsChanged];
end;
end;
procedure TProjectDefineTemplates.BeginUpdate;
begin
inc(FUpdateLock);
end;
procedure TProjectDefineTemplates.EndUpdate;
begin
if FUpdateLock=0 then RaiseException('TProjectDefineTemplates.EndUpdate');
dec(FUpdateLock);
if FUpdateLock=0 then begin
if ptfFlagsChanged in FFlags then CompilerFlagsChanged;
end;
end;
procedure TProjectDefineTemplates.UpdateMain;
begin
// update the package block define template (the container for all other
// define templates of the package)
if FMain=nil then begin
// create the main project template
FMain:=CreateProjectTemplate(FProjectDir);
FMain.SetDefineOwner(Owner,false);
FMain.SetFlags([dtfAutoGenerated],[],false);
end;
// ClearCache is here unnessary, because it is only a block
end;
procedure TProjectDefineTemplates.CompilerFlagsChanged;
begin
if FUpdateLock>0 then begin
Include(FFlags,ptfFlagsChanged);
exit;
end;
Exclude(FFlags,ptfFlagsChanged);
if FMain=nil then UpdateMain;
UpdateCompilerOptionsTemplates(FProjectDir,Owner.CompilerOptions,true,true);
end;
procedure TProjectDefineTemplates.AllChanged;
begin
CompilerFlagsChanged;
UpdateGlobalValues;
CodeToolBoss.DefineTree.ClearCache;
end;
procedure TProjectDefineTemplates.UpdateGlobalValues;
var
NewProjectDir: String;
Changed: Boolean;
begin
Changed:=false;
Changed:=Changed or CodeToolBoss.SetGlobalValue(
ExternalMacroStart+'LCLWidgetType',
Owner.CompilerOptions.LCLWidgetType);
if Owner.IsVirtual then
NewProjectDir:=VirtualDirectory
else
NewProjectDir:=Owner.ProjectDirectory;
Changed:=Changed or CodeToolBoss.SetGlobalValue(
ExternalMacroStart+'ProjPath',NewProjectDir);
if Changed then
IncreaseCompilerParseStamp;
end;
end.
{
$Log$
Revision 1.140 2003/11/22 23:56:33 mattias
fixed win32 intf menu height from Wojciech
Revision 1.139 2003/10/15 18:01:10 mattias
implemented extract proc, check lfm and convert delphi unit
Revision 1.138 2003/10/11 08:33:22 mattias
added catalan
Revision 1.137 2003/09/18 09:21:02 mattias
renamed LCLLinux to LCLIntf
Revision 1.136 2003/09/17 08:43:17 mattias
fixed loading old project compiler options
Revision 1.135 2003/09/10 12:13:48 mattias
implemented Import and Export of compiler options
Revision 1.134 2003/08/20 15:06:57 mattias
implemented Build+Run File
Revision 1.133 2003/08/15 14:28:48 mattias
clean up win32 ifdefs
Revision 1.132 2003/07/14 09:03:39 mattias
deactivated FCL TDataModule
Revision 1.131 2003/07/08 17:30:19 mattias
fixed changing widget set and TStringGrid exceptions on ColCount=0
Revision 1.130 2003/06/25 17:22:47 mattias
added automatic linux-windows file conversions
Revision 1.129 2003/06/19 09:26:58 mattias
fixed changing unitname during update
Revision 1.128 2003/06/08 11:05:45 mattias
implemented filename case check before adding to project
Revision 1.127 2003/06/03 16:12:14 mattias
fixed loading bookmarks for editor index 0
Revision 1.126 2003/06/01 21:09:09 mattias
implemented datamodules
Revision 1.125 2003/06/01 11:23:01 mattias
splittet designer form and lookup root
Revision 1.124 2003/05/31 10:07:33 mattias
changed projects forms into components
Revision 1.123 2003/05/30 16:25:47 mattias
started datamodule
Revision 1.122 2003/05/26 21:03:27 mattias
added README, describing how to create a gtk2 lcl application
Revision 1.121 2003/05/23 14:12:51 mattias
implemented restoring breakpoints
Revision 1.120 2003/05/21 16:19:12 mattias
implemented saving breakpoints and watches
Revision 1.119 2003/05/12 14:47:45 mattias
reduced output
Revision 1.118 2003/05/12 13:11:34 mattias
implemented publish package
Revision 1.117 2003/05/02 10:28:59 mattias
improved file checking
Revision 1.116 2003/04/29 19:00:41 mattias
added package gtkopengl
Revision 1.115 2003/04/29 09:31:10 mattias
changed macro name ProjectDir to ProjPath
Revision 1.114 2003/04/24 16:44:28 mattias
implemented define templates for projects with packages
Revision 1.113 2003/04/21 16:21:28 mattias
implemented default package for custom IDE components
Revision 1.112 2003/04/20 23:10:03 mattias
implemented inherited project compiler options
Revision 1.111 2003/04/20 20:32:40 mattias
implemented removing, re-adding, updating project dependencies
Revision 1.110 2003/04/20 09:52:07 mattias
implemented saving loading project dependencies
Revision 1.109 2003/04/20 07:36:29 mattias
fixed loading form name
Revision 1.108 2003/04/18 15:32:51 mattias
implemented file reference list
Revision 1.107 2003/04/16 13:48:10 mattias
implemented creating compiler option string for packages
Revision 1.106 2003/04/15 17:58:28 mattias
implemented inherited Compiler Options View
Revision 1.105 2003/04/15 08:54:27 mattias
fixed TMemo.WordWrap
Revision 1.104 2003/04/14 18:03:47 mattias
implemented inherited compiler options
Revision 1.103 2003/04/13 13:45:04 mattias
implemented broken dependencies dialog
Revision 1.102 2003/04/07 23:49:03 mattias
implemented adding units to packages
Revision 1.101 2003/03/29 21:41:19 mattias
fixed path delimiters for environment directories
Revision 1.100 2003/03/29 17:20:04 mattias
added TMemoScrollBar
Revision 1.99 2003/03/25 17:11:16 mattias
set Project.AutoCreateForms default to true
Revision 1.98 2003/03/11 09:57:51 mattias
implemented ProjectOpt: AutoCreateNewForms, added designer Show Options
Revision 1.97 2003/03/08 21:51:57 mattias
make resource string dialog nearly complete
Revision 1.96 2003/03/07 13:32:40 mattias
fixed checking readonly for non existing files
Revision 1.95 2003/03/07 11:41:21 mattias
fixed readonly check and added script to quick create lazarus snapshot
Revision 1.94 2003/02/28 19:10:25 mattias
added new ... dialog
Revision 1.93 2003/02/28 15:38:00 mattias
bookmarks are now saved also for closed files and merged when possible
Revision 1.92 2003/02/28 10:14:28 mattias
started package system (packager)
Revision 1.91 2003/02/26 12:44:52 mattias
readonly flag is now only saved if user set
Revision 1.90 2003/01/15 09:08:08 mattias
fixed search paths for virtual projects
Revision 1.89 2003/01/02 04:33:55 mattias
implemented incremental find and unit usage counts
Revision 1.88 2002/12/28 13:26:36 mattias
reduced lpi size
Revision 1.87 2002/12/28 12:42:38 mattias
focus fixes, reduced lpi size
Revision 1.86 2002/11/16 13:56:20 mattias
project now notices, if compiler options changed
Revision 1.85 2002/10/30 22:28:49 lazarus
MG: fixed used virtual files and IsPartOfProject Bug
Revision 1.84 2002/10/26 15:15:43 lazarus
MG: broke LCL<->interface circles
Revision 1.83 2002/10/13 09:35:37 lazarus
MG: added publish project
Revision 1.82 2002/10/04 21:31:56 lazarus
MG: added some component rename checks
Revision 1.81 2002/10/02 16:16:39 lazarus
MG: accelerated unitdependencies
Revision 1.80 2002/09/30 23:45:58 lazarus
MG: added part of project list to project
Revision 1.79 2002/09/30 23:41:00 lazarus
MG: added part of project list to project
Revision 1.78 2002/09/30 11:01:43 lazarus
MG: accelerated xmlwriter
Revision 1.77 2002/09/20 13:11:11 lazarus
MG: fixed TPanel and Frame3D
Revision 1.76 2002/09/20 11:40:07 lazarus
MG: added Move Page Left/Right for sourcenotebook
Revision 1.75 2002/09/13 16:58:26 lazarus
MG: removed the 1x1 bitmap from TBitBtn
Revision 1.74 2002/09/05 19:03:36 lazarus
MG: improved handling of ambigious source files
Revision 1.73 2002/08/23 07:05:15 lazarus
MG: started form renaming
Revision 1.72 2002/08/21 07:16:59 lazarus
MG: reduced mem leak of clipping stuff, still not fixed
Revision 1.71 2002/08/07 09:55:28 lazarus
MG: codecompletion now checks for filebreaks, savefile now checks for filedate
Revision 1.70 2002/08/01 14:10:30 lazarus
MG: started file access monitoring for loaded files
Revision 1.69 2002/08/01 08:03:03 lazarus
MG: accelerated searches in project
Revision 1.68 2002/07/31 06:52:17 lazarus
MG: started File Access Monitoring for hidden files
Revision 1.67 2002/07/30 06:24:04 lazarus
MG: added a faster version of TXMLConfig
Revision 1.66 2002/07/06 06:37:06 lazarus
MG: added Revert
Revision 1.65 2002/05/16 13:00:57 lazarus
MG: fixed changing syntax highlighter on save as
Revision 1.64 2002/05/10 06:57:45 lazarus
MG: updated licenses
Revision 1.63 2002/04/28 14:10:29 lazarus
MG: fixes for saving resource files
Revision 1.62 2002/04/21 13:24:06 lazarus
MG: small updates and fixes
Revision 1.61 2002/04/15 12:45:57 lazarus
MG: added save projectunit flags
Revision 1.60 2002/04/05 16:34:16 lazarus
MG: fixed autocreate form editing in project opts
Revision 1.59 2002/04/04 17:21:18 lazarus
MG: fixed outputfilter for linker errors
Revision 1.58 2002/04/02 17:18:25 lazarus
MG: fixed save project as, renaming source name
Revision 1.57 2002/03/28 00:11:06 lazarus
MG: removed unused
Revision 1.56 2002/03/25 16:48:26 lazarus
MG: clean ups for main.pp, many minor fixes
Revision 1.55 2002/03/25 07:29:23 lazarus
MG: added TOpen/SaveFlags and splittet some methods
Revision 1.54 2002/03/22 12:36:45 lazarus
MG: many fixes, to make it short: events
Revision 1.53 2002/03/21 23:59:59 lazarus
MG: code creation options applied to new unit source
Revision 1.52 2002/03/21 22:44:08 lazarus
MG: fixes for save-as and form streaming exceptions
Revision 1.51 2002/03/05 08:14:59 lazarus
MG: updates for codetools defines editor
Revision 1.50 2002/02/25 23:18:54 lazarus
MG: jump history will now try to save relative filenames
Revision 1.49 2002/02/08 21:08:00 lazarus
MG: saving of virtual project files will now save the whole project
Revision 1.48 2002/02/03 00:23:55 lazarus
TPanel implemented.
Basic graphic primitives split into GraphType package, so that we can
reference it from interface (GTK, Win32) units.
New Frame3d canvas method that uses native (themed) drawing (GTK only).
New overloaded Canvas.TextRect method.
LCLLinux and Graphics was split, so a bunch of files had to be modified.
Revision 1.47 2001/12/19 22:09:14 lazarus
MG: added GUID and alias parsing, added DoJumpToCodeToolBossError
Revision 1.46 2001/12/16 22:24:54 lazarus
MG: changes for new compiler 20011216
Revision 1.45 2001/12/13 23:09:58 lazarus
MG: enhanced code caching, fixed CursorToCleanPos and beautify statement
Revision 1.44 2001/12/02 11:03:36 lazarus
MG: added default pascal file extension option
Revision 1.43 2001/12/01 22:17:26 lazarus
MG: added jump-history
Revision 1.42 2001/11/17 09:48:56 lazarus
MG: changing project filename will now also change the title
Revision 1.41 2001/11/15 13:49:50 lazarus
MG: fixed open non existing file and unitname in save project as
Revision 1.40 2001/11/14 17:46:57 lazarus
Changes to make toggling between form and unit work.
Added BringWindowToTop
Shane
Revision 1.39 2001/11/06 22:20:30 lazarus
MG: started breakpoint and watch frontend
Revision 1.38 2001/11/06 16:42:23 lazarus
MG: added facade for find in files
Revision 1.36 2001/11/06 15:47:32 lazarus
MG: added build all
Revision 1.35 2001/11/06 12:20:33 lazarus
MG: added Run Parameter Options - not enabled yet
Revision 1.34 2001/11/05 18:18:18 lazarus
added popupmenu+arrows to notebooks, added target filename
Revision 1.33 2001/11/03 08:37:35 lazarus
MG: fixed errorline showing, resource adding and published var editing and added make cleanall
Revision 1.32 2001/10/23 09:13:52 lazarus
MG: fixed TestProject
Revision 1.31 2001/10/18 13:01:31 lazarus
MG: fixed speedbuttons numglyphs>1 and started IDE debugging
Revision 1.30 2001/10/15 13:11:27 lazarus
MG: added complete code
Revision 1.27 2001/10/09 09:46:50 lazarus
MG: added codetools, fixed synedit unindent, fixed MCatureHandle
Revision 1.26 2001/07/08 22:33:56 lazarus
MG: added rapid testing project
Revision 1.25 2001/06/27 21:43:23 lazarus
MG: added project bookmark support
Revision 1.24 2001/06/04 09:32:17 lazarus
MG: fixed bugs and cleaned up messages
Revision 1.23 2001/05/27 11:52:00 lazarus
MG: added --primary-config-path=<filename> cmd line option
Revision 1.20 2001/04/04 13:55:35 lazarus
MG: finished TComponentPropertyEditor, added OnModified to oi, cfe and designer
Revision 1.19 2001/04/04 12:20:34 lazarus
MG: added add to/remove from project, small bugfixes
Revision 1.18 2001/03/29 12:38:59 lazarus
MG: new environment opts, ptApplication bugfixes
Revision 1.17 2001/03/26 14:52:30 lazarus
MG: TSourceLog + compiling bugfixes
Revision 1.16 2001/03/19 14:00:47 lazarus
MG: fixed many unreleased DC and GDIObj bugs
Revision 1.15 2001/03/09 17:54:45 lazarus
Fixed error in Windows section of OnLoadSaveFilename - missing ')'
Revision 1.14 2001/03/09 11:38:20 lazarus
auto load last project
Revision 1.10 2001/03/03 11:06:15 lazarus
added project support, codetools
Revision 1.8 2001/02/22 17:04:57 lazarus
added environment options + killed ide unit circles
Revision 1.7 2001/02/08 06:08:13 lazarus
Began adding code to save project to the output directory. Added TODO
comments and cleaned up some of the code. CAW
Revision 1.6 2001/01/31 13:03:33 lazarus
Commitng source with new editor.
Shane
Revision 1.5 2001/01/31 06:28:41 lazarus
Removed global unit.
Renamed TProjectUnitInfo to TUnitInfo.
Added Source property to both TUnitInfo and TProject to hold source code
for units and project.
Added functions to load and save units to TUnitInfo.
Added code to save and load units when a project is saved and loaded. CAW
Revision 1.4 2001/01/29 05:42:41 lazarus
Created new TProjectUnitInfo class.
Created new TProject class. Saves to XML config file.
Moved compiler options to write to the project file. CAW
Revision 1.3 2001/01/04 20:33:53 lazarus
Moved lresources.
Moved CreateLFM to Main.pp
Changed Form1 and TFOrm1 to MainIDE and TMainIDE
Shane
Revision 1.2 2000/12/19 18:43:13 lazarus
Removed IDEEDITOR. This causes the PROJECT class to not function.
Saving projects no longer works.
I added TSourceNotebook and TSourceEditor. They do all the work for saving/closing/opening units. Somethings work but they are in early development.
Shane
Revision 1.1 2000/07/13 10:27:48 michael
+ Initial import
}