lazarus/ide/project.pp
lazarus 36975e1117 MG: fixed bugs and cleaned up messages
git-svn-id: trunk@280 -
2001-06-04 09:32:17 +00:00

1530 lines
47 KiB
ObjectPascal

{
/***************************************************************************
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 program 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. *
* *
***************************************************************************/
}
unit project;
{$mode objfpc}{$H+}
{$ifdef Trace}
{$ASSERTIONS ON}
{$endif}
interface
uses
Classes, SysUtils, LCLLinux, XMLCfg, LazConf, CompilerOptions, FileCtrl,
CodeTools, Forms, Controls, EditorOptions, Dialogs, IDEProcs;
type
//---------------------------------------------------------------------------
TProjectBookmark = class
private
fCursorPos: TPoint;
fEditorIndex: integer;
fID: integer;
public
property CursorPos: TPoint read fCursorPos write fCursorPos;
property EditorIndex: integer read fEditorIndex write fEditorIndex;
property ID:integer read fID write fID;
procedure SaveToXMLConfig(XMLConfig: TXMLConfig; Path: string);
procedure LoadFromXMLConfig(XMLConfig: TXMLConfig; Path: string);
end;
TProjectBookmarkList = class
private
FBookmarks:TList; // list of TProjectBookmark
function GetBookmarks(Index:integer):TProjectBookmark;
procedure SetBookmarks(Index:integer; ABookmark: TProjectBookmark);
public
constructor Create;
destructor Destroy; override;
property Items[Index:integer]:TProjectBookmark
read GetBookmarks write SetBookmarks; default;
function Count:integer;
procedure Delete(Index:integer);
procedure Clear;
function Add(ABookmark: TProjectBookmark):integer;
procedure DeleteAllWithEditorIndex(EditorIndex:integer);
function IndexOfID(ID:integer):integer;
procedure SaveToXMLConfig(XMLConfig: TXMLConfig; Path: string);
procedure LoadFromXMLConfig(XMLConfig: TXMLConfig; Path: string);
end;
//---------------------------------------------------------------------------
TProjectBreakPoint = class
private
fLineNumber: integer;
// ToDo: conditions, active/non active ...
public
property LineNumber:integer read fLineNumber write fLineNumber;
procedure SaveToXMLConfig(XMLConfig: TXMLConfig; Path: string);
procedure LoadFromXMLConfig(XMLConfig: TXMLConfig; Path: string);
end;
TProjectBreakPointList = class
private
FBreakPoints:TList; // list of TProjectBreakPoint
function GetBreakPoints(Index:integer):TProjectBreakPoint;
procedure SetBreakPoints(Index:integer; ABreakPoint: TProjectBreakPoint);
public
constructor Create;
destructor Destroy; override;
property Items[Index:integer]:TProjectBreakPoint
read GetBreakPoints write SetBreakPoints; default;
function Count:integer;
procedure Delete(Index:integer);
procedure Clear;
function Add(ABreakPoint: TProjectBreakPoint):integer;
procedure SaveToXMLConfig(XMLConfig: TXMLConfig; Path: string);
procedure LoadFromXMLConfig(XMLConfig: TXMLConfig; Path: string);
end;
//---------------------------------------------------------------------------
TUnitInfo = class;
TOnFileBackup = function(const FileToBackup:string;
IsPartOfProject:boolean):TModalResult of object;
TOnLoadSaveFilename = procedure(var Filename:string; Load:boolean) of object;
TOnUnitNameChange = procedure(AnUnitInfo: TUnitInfo;
const OldUnitName, NewUnitName: string; var Allowed: boolean) of object;
//---------------------------------------------------------------------------
TNewUnitType = (
nuEmpty, // no code
nuUnit, // unit
nuForm, // unit with form
nuCustomProgram // program
);
TUnitInfo = class(TObject)
private
{ Variables }
fBreakpoints: TProjectBreakPointList;
fCursorPos: TPoint;
fEditorIndex: integer;
fFilename: String;
fForm: TComponent;
fFormName: string; // classname is always T<fFormName>
// this attribute contains the formname even if the unit is not loaded
fHasResources: boolean;
fIsPartOfProject: boolean;
fLoaded: Boolean; // loaded in the source editor
fModified: boolean;
fOnFileBackup: TOnFileBackup;
fOnLoadSaveFilename: TOnLoadSaveFilename;
fOnUnitNameChange: TOnUnitNameChange;
fReadOnly: Boolean;
fSource: TSourceLog;
fSyntaxHighlighter: TLazSyntaxHighlighter;
fTopLine: integer;
fUnitName: String;
function GetHasResources:boolean;
procedure SetUnitName(NewUnitName:string);
public
constructor Create;
destructor Destroy; override;
function ReadUnitSource(ReadUnitName:boolean): TModalResult;
function WriteUnitSource: TModalResult;
procedure SaveToXMLConfig(XMLConfig: TXMLConfig; Path: string);
procedure LoadFromXMLConfig(XMLConfig: TXMLConfig; Path: string);
procedure Clear;
procedure CreateStartCode(NewUnitType: TNewUnitType);
{ Properties }
property Breakpoints: TProjectBreakPointList
read fBreakpoints write fBreakpoints;
property CursorPos: TPoint read fCursorPos write fCursorPos;
property EditorIndex:integer read fEditorIndex write fEditorIndex;
property Filename: String read fFilename write fFilename;
property Form: TComponent read fForm write fForm;
property FormName: string read fFormName write fFormName;
property HasResources: boolean read GetHasResources write fHasResources;
property IsPartOfProject:boolean
read fIsPartOfProject write fIsPartOfProject;
property Loaded: Boolean read fLoaded write fLoaded;
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 ReadOnly: Boolean read fReadOnly write fReadOnly;
property Source: TSourceLog read fSource write fSource;
property SyntaxHighlighter: TLazSyntaxHighlighter
read fSyntaxHighlighter write fSyntaxHighlighter;
property TopLine: integer read fTopLine write fTopLine;
property UnitName: String read fUnitName write SetUnitName;
end;
//---------------------------------------------------------------------------
TProjectType = // for a description see ProjectTypeDescriptions
(ptApplication, ptProgram, ptCustomProgram);
TProject = class(TObject)
private
xmlcfg: TXMLConfig;
{ Variables }
fActiveEditorIndexAtStart: integer;
fBookmarks: TProjectBookmarkList;
fCompilerOptions: TCompilerOptions;
fIconPath: String;
fMainUnit: Integer; // only for ptApplication
fModified: boolean;
fOnFileBackup: TOnFileBackup;
fOutputDirectory: String;
fProjectFile: String; // the lpi filename
fProjectType: TProjectType;
fTargetFileExt: String;
fTitle: String;
fUnitList: TList; // list of TUnitInfo
fUnitOutputDirectory: String;
function GetUnits(Index:integer):TUnitInfo;
procedure SetUnits(Index:integer; AUnitInfo: TUnitInfo);
procedure SetProjectFile(NewProjectFilename: string);
function OnUnitFileBackup(const Filename:string;
IsPartOfProject:boolean):TModalResult;
function GetProjectInfoFile:string;
procedure SetProjectInfoFile(NewFilename:string);
procedure OnLoadSaveFilename(var AFilename:string; Load:boolean);
procedure OnUnitNameChange(AnUnitInfo: TUnitInfo;
const OldUnitName, NewUnitName: string; var Allowed: boolean);
public
constructor Create(TheProjectType: TProjectType);
destructor Destroy; override;
function ReadProject(LPIFilename: string): TModalResult;
function WriteProject: TModalResult;
property Units[Index: integer]:TUnitInfo read GetUnits write SetUnits;
function UnitCount:integer;
function NewUniqueUnitName:string;
procedure AddUnit(AUnit: TUnitInfo; AddToProjectFile:boolean);
procedure RemoveUnit(Index:integer);
function IndexOf(AUnitInfo: TUnitInfo):integer;
function IndexOfUnitWithName(AUnitName:string;
OnlyProjectUnits:boolean):integer;
function IndexOfUnitWithForm(AForm: TComponent;
OnlyProjectUnits:boolean):integer;
function UnitWithEditorIndex(Index:integer):TUnitInfo;
procedure CloseEditorIndex(EditorIndex:integer);
procedure InsertEditorIndex(EditorIndex:integer);
procedure Clear;
function SomethingModified: boolean;
function AddCreateFormToProjectFile(AClassName,AName:string):boolean;
function RemoveCreateFormFromProjectFile(AClassName,AName:string):boolean;
function FormIsCreatedInProjectFile(AClassname,AName:string):boolean;
function UnitIsUsed(AUnitName:string):boolean;
function GetResourceFilename(AnUnitInfo: TUnitInfo; Index:integer):string;
function SearchIncludeFile(AnUnitInfo: TUnitInfo; Filename:string):string;
function SearchFile(Filename,SearchPaths,InitialDir:string):string;
function SearchResourceFilename(AnUnitInfo: TUnitInfo):string;
property ActiveEditorIndexAtStart: integer
read fActiveEditorIndexAtStart write fActiveEditorIndexAtStart;
property Bookmarks: TProjectBookmarkList read fBookmarks write fBookmarks;
property CompilerOptions: TCompilerOptions
read fCompilerOptions write fCompilerOptions;
property IconPath: String read fIconPath write fIconPath;
property MainUnit: Integer //this is the unit index of the program file
read fMainUnit write fMainUnit;
property Modified: boolean read fModified write fModified;
property OnFileBackup: TOnFileBackup read fOnFileBackup write fOnFileBackup;
property OutputDirectory: String read fOutputDirectory write fOutputDirectory;
property ProjectFile: String read fProjectFile write SetProjectFile;
property ProjectInfoFile: string
read GetProjectInfoFile write SetProjectInfoFile;
property ProjectType: TProjectType read fProjectType write fProjectType;
property TargetFileExt: String read fTargetFileExt write fTargetFileExt;
property Title: String read fTitle write fTitle;
property UnitOutputDirectory: String
read fUnitOutputDirectory write fUnitOutputDirectory;
end;
const
ResourceFileExt = '.lrs';
ProjectTypeNames : array[TProjectType] of string = (
'Application', 'Program', 'Custom program'
);
ProjectTypeDescriptions : array[TProjectType] of string = (
// ptApplication
'Application'#13
+'A graphical lcl/freepascal program. The program file is '
+'automatically maintained by lazarus.'
// ptProgram
,'Program:'#13
+'A freepascal program. The program file is automatically '
+'maintained by lazarus.'
// ptCustomProgram
,'Custom program:'#13
+'A freepascal program.'
);
ProjectDefaultExt : array[TProjectType] of string = (
'.lpr','.pp','.pp'
);
function ProjectTypeNameToType(s:string): TProjectType;
implementation
function ProjectTypeNameToType(s:string): TProjectType;
begin
for Result:=Low(TProjectType) to High(TProjectType) do
if (lowercase(ProjectTypeNames[Result])=lowercase(s)) then exit;
Result:=ptCustomProgram;
end;
{ TProjectBookmark }
procedure TProjectBookmark.SaveToXMLConfig(XMLConfig: TXMLConfig;
Path: string);
begin
XMLConfig.SetValue(Path+'CursorPosX',CursorPos.X);
XMLConfig.SetValue(Path+'CursorPosY',CursorPos.Y);
XMLConfig.SetValue(Path+'EditorIndex',EditorIndex);
end;
procedure TProjectBookmark.LoadFromXMLConfig(XMLConfig: TXMLConfig;
Path: string);
begin
CursorPos.X:=XMLConfig.GetValue(Path+'CursorPosX',0);
CursorPos.Y:=XMLConfig.GetValue(Path+'CursorPosY',0);
EditorIndex:=XMLConfig.GetValue(Path+'EditorIndex',-1);
end;
{ TProjectBookmarkList }
constructor TProjectBookmarkList.Create;
begin
inherited Create;
fBookmarks:=TList.Create;
end;
destructor TProjectBookmarkList.Destroy;
begin
Clear;
fBookmarks.Free;
inherited Destroy;
end;
procedure TProjectBookmarkList.Clear;
var a:integer;
begin
for a:=0 to fBookmarks.Count-1 do Items[a].Free;
fBookmarks.Clear;
end;
function TProjectBookmarkList.Count:integer;
begin
Result:=fBookmarks.Count;
end;
function TProjectBookmarkList.GetBookmarks(Index:integer):TProjectBookmark;
begin
Result:=TProjectBookmark(fBookmarks[Index]);
end;
procedure TProjectBookmarkList.SetBookmarks(Index:integer;
ABookmark: TProjectBookmark);
begin
fBookmarks[Index]:=ABookmark;
end;
function TProjectBookmarkList.IndexOfID(ID:integer):integer;
begin
Result:=Count-1;
while (Result>=0) and (Items[Result].ID<>ID) do dec(Result);
end;
procedure TProjectBookmarkList.Delete(Index:integer);
begin
Items[Index].Free;
fBookmarks.Delete(Index);
end;
procedure TProjectBookmarkList.DeleteAllWithEditorIndex(
EditorIndex:integer);
var i:integer;
begin
i:=Count-1;
while (i>=0) do begin
if Items[i].EditorIndex=EditorIndex then Delete(i);
dec(i);
end;
end;
function TProjectBookmarkList.Add(ABookmark: TProjectBookmark):integer;
begin
Result:=fBookmarks.Add(ABookmark);
end;
procedure TProjectBookmarkList.SaveToXMLConfig(XMLConfig: TXMLConfig;
Path: string);
var a:integer;
begin
XMLConfig.SetValue(Path+'Bookmarks/Count',Count);
for a:=0 to Count-1 do
Items[a].SaveToXMLConfig(XMLConfig,Path+'Bookmarks/Mark'+IntToStr(a)+'/');
end;
procedure TProjectBookmarkList.LoadFromXMLConfig(XMLConfig: TXMLConfig;
Path: string);
var a,NewCount:integer;
NewBookmark:TProjectBookmark;
begin
Clear;
NewCount:=XMLConfig.GetValue(Path+'Bookmarks/Count',0);
for a:=0 to NewCount-1 do begin
NewBookmark:=TProjectBookmark.Create;
Add(NewBookmark);
NewBookmark.LoadFromXMLConfig(XMLConfig,Path+'Bookmarks/Mark'+IntToStr(a)+'/');
end;
end;
{ TProjectBreakPoint }
procedure TProjectBreakPoint.SaveToXMLConfig(XMLConfig: TXMLConfig;
Path: string);
begin
XMLConfig.SetValue(Path+'LineNumber',LineNumber);
end;
procedure TProjectBreakPoint.LoadFromXMLConfig(XMLConfig: TXMLConfig;
Path: string);
begin
LineNumber:=XMLConfig.GetValue(Path+'LineNumber',-1);
end;
{ TProjectBreakPointList }
constructor TProjectBreakPointList.Create;
begin
inherited Create;
fBreakPoints:=TList.Create;
end;
destructor TProjectBreakPointList.Destroy;
begin
Clear;
fBreakPoints.Free;
inherited Destroy;
end;
procedure TProjectBreakPointList.Clear;
var a:integer;
begin
for a:=0 to fBreakPoints.Count-1 do Items[a].Free;
fBreakPoints.Clear;
end;
function TProjectBreakPointList.Count:integer;
begin
Result:=fBreakPoints.Count;
end;
function TProjectBreakPointList.GetBreakPoints(Index:integer):TProjectBreakPoint;
begin
Result:=TProjectBreakPoint(fBreakPoints[Index]);
end;
procedure TProjectBreakPointList.SetBreakPoints(Index:integer;
ABreakPoint: TProjectBreakPoint);
begin
fBreakPoints[Index]:=ABreakPoint;
end;
procedure TProjectBreakPointList.Delete(Index:integer);
begin
Items[Index].Free;
fBreakPoints.Delete(Index);
end;
function TProjectBreakPointList.Add(ABreakPoint: TProjectBreakPoint):integer;
begin
Result:=fBreakPoints.Add(ABreakPoint);
end;
procedure TProjectBreakPointList.SaveToXMLConfig(XMLConfig: TXMLConfig;
Path: string);
var a:integer;
begin
XMLConfig.SetValue(Path+'BreakPoints/Count',Count);
for a:=0 to Count-1 do
Items[a].SaveToXMLConfig(XMLConfig,Path+'BreakPoints/Point'+IntToStr(a)+'/');
end;
procedure TProjectBreakPointList.LoadFromXMLConfig(XMLConfig: TXMLConfig;
Path: string);
var a,NewCount:integer;
NewBreakPoint:TProjectBreakPoint;
begin
Clear;
NewCount:=XMLConfig.GetValue(Path+'BreakPoints/Count',0);
for a:=0 to NewCount-1 do begin
NewBreakPoint:=TProjectBreakPoint.Create;
Add(NewBreakPoint);
NewBreakPoint.LoadFromXMLConfig(XMLConfig
,Path+'BreakPoints/Point'+IntToStr(a)+'/');
end;
end;
{------------------------------------------------------------------------------
TUnitInfo Class
------------------------------------------------------------------------------}
{------------------------------------------------------------------------------
TUnitInfo Constructor
------------------------------------------------------------------------------}
constructor TUnitInfo.Create;
begin
inherited Create;
Assert(False, 'Project Unit Info Class Created');
fSource := TSourceLog.Create('');
fBreakPoints:=TProjectBreakPointList.Create;
Clear;
end;
{------------------------------------------------------------------------------
TUnitInfo Destructor
------------------------------------------------------------------------------}
destructor TUnitInfo.Destroy;
begin
fBreakPoints.Free;
fSource.Free;
inherited Destroy;
end;
{------------------------------------------------------------------------------
TUnitInfo WriteUnitSource
------------------------------------------------------------------------------}
function TUnitInfo.WriteUnitSource: TModalResult;
var
ACaption:string;
AText:string;
fs: TFileStream;
begin
if Assigned(fOnFileBackup) then begin
Result:=fOnFileBackup(fFilename,IsPartOfProject);
if Result=mrAbort then exit;
end;
repeat
try
fs:=TFileStream.Create(fFilename,fmCreate);
try
fs.Write(Source.Source[1],Length(Source.Source));
finally
fs.Free;
end;
except
ACaption:='Write error';
AText:='Unable to write file "'+fFilename+'"!';
Result:=Application.MessageBox(PChar(AText),PChar(ACaption)
,MB_ABORTRETRYIGNORE);
if Result=mrAbort then exit;
if Result=mrIgnore then Result:=mrOk;
end;
until Result<>mrRetry;
Result:=mrOk;
end;
{------------------------------------------------------------------------------
TUnitInfo ReadUnitSource
------------------------------------------------------------------------------}
function TUnitInfo.ReadUnitSource(ReadUnitName:boolean): TmodalResult;
var UnitNameStart,UnitNameEnd:integer;
ACaption:string;
AText:string;
fs: TFileStream;
s: string;
begin
repeat
try
fs:=TFileStream.Create(fFilename,fmOpenRead);
try
Setlength(s,fs.Size);
fs.Read(s[1],Length(s));
Source.Source:=s;
finally
fs.Free;
end;
except
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;
until Result<>mrRetry;
if ReadUnitName then
fUnitName:=FindUnitNameInSource(Source.Source,UnitNameStart,UnitNameEnd);
Result:=mrOk;
end;
{------------------------------------------------------------------------------
TUnitInfo Clear
------------------------------------------------------------------------------}
procedure TUnitInfo.Clear;
begin
fBreakPoints.Clear;
fCursorPos.X := -1;
fCursorPos.Y := -1;
fEditorIndex := -1;
fFilename := '';
fForm := nil;
fFormName := '';
fHasResources := false;
fIsPartOfProject := false;
fLoaded := false;
fModified := false;
fReadOnly := false;
fSource.Clear;
fSyntaxHighlighter := lshFreePascal;
fTopLine := -1;
fUnitName := '';
end;
{------------------------------------------------------------------------------
TUnitInfo SaveToXMLConfig
------------------------------------------------------------------------------}
procedure TUnitInfo.SaveToXMLConfig(XMLConfig: TXMLConfig; Path: string);
var AFilename:string;
begin
XMLConfig.SetValue(Path+'CursorPos/X',fCursorPos.X);
XMLConfig.SetValue(Path+'CursorPos/Y',fCursorPos.Y);
XMLConfig.SetValue(Path+'EditorIndex/Value',fEditorIndex);
AFilename:=Filename;
if Assigned(fOnLoadSaveFilename) then
fOnLoadSaveFilename(AFilename,false);
XMLConfig.SetValue(Path+'Filename/Value',AFilename);
XMLConfig.SetValue(Path+'FormName/Value',fFormName);
XMLConfig.SetValue(Path+'HasResources/Value',fHasResources);
XMLConfig.SetValue(Path+'IsPartOfProject/Value',fIsPartOfProject);
XMLConfig.SetValue(Path+'Loaded/Value',fLoaded);
XMLConfig.SetValue(Path+'ReadOnly/Value',fReadOnly);
XMLConfig.SetValue(Path+'SyntaxHighlighter/Value'
,LazSyntaxHighlighterNames[fSyntaxHighlighter]);
XMLConfig.SetValue(Path+'TopLine/Value',fTopLine);
XMLConfig.SetValue(Path+'UnitName/Value',fUnitName);
fBreakpoints.SaveToXMLConfig(XMLConfig,Path);
end;
{------------------------------------------------------------------------------
TUnitInfo LoadFromXMLConfig
------------------------------------------------------------------------------}
procedure TUnitInfo.LoadFromXMLConfig(XMLConfig: TXMLConfig; 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;
fFormName:=XMLConfig.GetValue(Path+'FormName/Value','');
HasResources:=XMLConfig.GetValue(Path+'HasResources/Value',false);
fIsPartOfProject:=XMLConfig.GetValue(Path+'IsPartOfProject/Value',false);
fLoaded:=XMLConfig.GetValue(Path+'Loaded/Value',false);
fReadOnly:=XMLConfig.GetValue(Path+'ReadOnly/Value',false);
fSyntaxHighlighter:=StrToLazSyntaxHighlighter(XMLConfig.GetValue(
Path+'SyntaxHighlighter/Value',''));
fTopLine:=XMLConfig.GetValue(Path+'TopLine/Value',-1);
UnitName:=XMLConfig.GetValue(Path+'UnitName/Value','');
fBreakpoints.LoadFromXMLConfig(XMLConfig,Path);
end;
procedure TUnitInfo.SetUnitName(NewUnitName:string);
var NewIncludeFilename:string;
IncludeStart,IncludeEnd:integer;
Allowed:boolean;
begin
if fUnitName<>NewUnitName then begin
if NewUnitName<>'' then begin
Allowed:=true;
if Assigned(fOnUnitNameChange) then
fOnUnitNameChange(Self,fUnitName,NewUnitName,Allowed);
if not Allowed then exit;
RenameUnitInSource(Source,NewUnitName);
if FindIncludeDirective(Source.Source,'initialization',1
,IncludeStart,IncludeEnd) then
begin
NewIncludeFilename:=NewUnitName+ResourceFileExt;
Source.Replace(IncludeStart,IncludeEnd-IncludeStart,
'{$I '+NewIncludeFilename+'}');
end;
fUnitName:=NewUnitName;
fModified:=true;
end;
end;
end;
procedure TUnitInfo.CreateStartCode(NewUnitType: TNewUnitType);
var ResourceFilename:string;
NewSource: TStringList;
begin
ResourceFilename:=fUnitName+ResourceFileExt;
NewSource:=TStringList.Create;
if NewUnitType in [nuForm,nuUnit] then with NewSource do begin
Add('unit '+fUnitName+';');
Add('');
Add('{$mode objfpc}{$H+}');
Add('');
Add('interface');
Add('');
Add('uses');
case NewUnitType of
nuUnit:
begin
Add(' Classes, SysUtils;');
Add('');
Add('implementation');
end;
nuForm:
begin
Add(' Classes, SysUtils, Forms, Controls, Graphics, Dialogs, LResources;');
Add('');
Add('type');
Add(' T'+fFormName+' = class(TForm)');
Add(' private');
Add(' { private declarations }');
Add(' public');
Add(' { public declarations }');
Add(' end;');
Add('');
Add('var');
Add(' '+fFormName+': T'+fFormName+';');
Add('');
Add('implementation');
Add('');
Add('initialization');
Add(' {$I '+ResourceFilename+'}');
end;
end;
Add('');
Add('end.');
Add('');
end else if NewUnitType in [nuCustomProgram] then with NewSource do begin
Add('program CustomProgram;');
Add('');
Add('{$mode objfpc}{$H+}');
Add('');
Add('uses');
Add(' Classes, SysUtils;');
Add('');
Add('begin');
Add('end.');
Add('');
end;
Source.Source:=NewSource.Text;
NewSource.Free;
fModified:=true;
end;
function TUnitInfo.GetHasResources:boolean;
begin
Result:=fHasResources or (FormName<>'');
end;
{------------------------------------------------------------------------------
TProject Class
------------------------------------------------------------------------------}
{------------------------------------------------------------------------------
TProject Constructor
------------------------------------------------------------------------------}
constructor TProject.Create(TheProjectType: TProjectType);
var PrgUnitInfo: TUnitInfo;
NewSource: TStringList;
begin
inherited Create;
Assert(False, 'Trace:Project Class Created');
XMLCfg := nil;
fProjectType:=TheProjectType;
fActiveEditorIndexAtStart := -1;
fBookmarks := TProjectBookmarkList.Create;
fCompilerOptions := TCompilerOptions.Create;
fIconPath := '';
fMainUnit := -1;
fModified := false;
fOutputDirectory := '.';
fProjectFile := '';
fTargetFileExt := '';
fTitle := '';
fUnitList := TList.Create; // list of TUnitInfo
fUnitOutputDirectory := '.';
// create program source
NewSource:=TStringList.Create;
case fProjectType of
ptProgram, ptApplication, ptCustomProgram:
begin
PrgUnitInfo:=TUnitInfo.Create;
PrgUnitInfo.IsPartOfProject:=true;
PrgUnitInfo.SyntaxHighlighter:=
ExtensionToLazSyntaxHighlighter(ProjectDefaultExt[fProjectType]);
AddUnit(PrgUnitInfo,false);
MainUnit:=0;
with NewSource do begin
Add('program Project1;');
Add('');
Add('{$mode objfpc}{$H+}');
Add('');
Add('uses');
case fProjectType of
ptProgram, ptCustomProgram: Add(' Classes;');
ptApplication: Add(' Forms;');
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;
Units[MainUnit].Source.Source:=NewSource.Text;
end;
end;
NewSource.Free;
end;
{------------------------------------------------------------------------------
TProject Destructor
------------------------------------------------------------------------------}
destructor TProject.Destroy;
begin
Clear;
fBookmarks.Free;
if (XMLCfg <> nil) then XMLCfg.Free;
fUnitList.Free;
fCompilerOptions.Free;
inherited Destroy;
end;
{------------------------------------------------------------------------------
TProject WriteProject
------------------------------------------------------------------------------}
function TProject.WriteProject: TModalResult;
var
confPath: String;
i: Integer;
AText, ACaption: string;
begin
Result := mrCancel;
confPath := ChangeFileExt(ProjectFile,'.lpi');
if Assigned(fOnFileBackup) then begin
Result:=fOnFileBackup(confPath,true);
if Result=mrAbort then exit;
end;
xmlcfg := TXMLConfig.Create(SetDirSeparators(confPath));
try
repeat
try
xmlcfg.SetValue('ProjectOptions/General/ProjectType/Value',
ProjectTypeNames[ProjectType]);
xmlcfg.SetValue('ProjectOptions/General/MainUnit/Value', MainUnit);
xmlcfg.SetValue('ProjectOptions/General/ActiveEditorIndexAtStart/Value'
,ActiveEditorIndexAtStart);
xmlcfg.SetValue('ProjectOptions/General/IconPath/Value', IconPath);
xmlcfg.SetValue('ProjectOptions/General/TargetFileExt/Value'
,TargetFileExt);
xmlcfg.SetValue('ProjectOptions/General/Title/Value', Title);
xmlcfg.SetValue('ProjectOptions/General/OutputDirectory/Value'
,OutputDirectory);
xmlcfg.SetValue('ProjectOptions/General/UnitOutputDirectory/Value'
,UnitOutputDirectory);
fBookmarks.SaveToXMLConfig(xmlcfg,'ProjectOptions/');
// Set options for each Unit
xmlcfg.SetValue('ProjectOptions/Units/Count',UnitCount);
for i := 0 to UnitCount - 1 do begin
Units[i].SaveToXMLConfig(
xmlcfg,'ProjectOptions/Units/Unit'+IntToStr(i)+'/');
end;
// Save the compiler options
CompilerOptions.XMLConfigFile := xmlcfg;
CompilerOptions.ProjectFile := confPath;
CompilerOptions.SaveCompilerOptions(true);
xmlcfg.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;
finally
xmlcfg.Free;
xmlcfg:=nil;
end;
Result := mrOk;
end;
{------------------------------------------------------------------------------
TProject ReadProject
------------------------------------------------------------------------------}
function TProject.ReadProject(LPIFilename: string): TModalResult;
var
NewUnitInfo: TUnitInfo;
NewUnitCount,i: integer;
begin
Result := mrCancel;
Clear;
ProjectInfoFile:=LPIFilename;
try
xmlcfg := TXMLConfig.Create(ProjectInfoFile);
except
MessageDlg('Unable to read the project info file "'+ProjectInfoFile+'".'
,mtError,[mbOk],0);
Result:=mrCancel;
exit;
end;
try
ProjectType := ProjectTypeNameToType(xmlcfg.GetValue(
'ProjectOptions/General/ProjectType/Value', ''));
MainUnit := xmlcfg.GetValue('ProjectOptions/General/MainUnit/Value', -1);
ActiveEditorIndexAtStart := xmlcfg.GetValue(
'ProjectOptions/General/ActiveEditorIndexAtStart/Value', -1);
IconPath := xmlcfg.GetValue('ProjectOptions/General/IconPath/Value', './');
TargetFileExt := xmlcfg.GetValue(
'ProjectOptions/General/TargetFileExt/Value', '');
Title := xmlcfg.GetValue('ProjectOptions/General/Title/Value', '');
OutputDirectory := xmlcfg.GetValue(
'ProjectOptions/General/OutputDirectory/Value', '.');
UnitOutputDirectory := xmlcfg.GetValue(
'ProjectOptions/General/UnitOutputDirectory/Value', '.');
fBookmarks.LoadFromXMLConfig(xmlcfg,'ProjectOptions/');
NewUnitCount:=xmlcfg.GetValue('ProjectOptions/Units/Count',0);
for i := 0 to NewUnitCount - 1 do begin
NewUnitInfo:=TUnitInfo.Create;
AddUnit(NewUnitInfo,false);
NewUnitInfo.LoadFromXMLConfig(
xmlcfg,'ProjectOptions/Units/Unit'+IntToStr(i)+'/');
end;
// Load the compiler options
CompilerOptions.XMLConfigFile := xmlcfg;
CompilerOptions.ProjectFile := ProjectFile;
CompilerOptions.LoadCompilerOptions(true);
finally
xmlcfg.Free;
xmlcfg:=nil;
end;
Result := mrOk;
end;
{------------------------------------------------------------------------------
TProject AddUnit
------------------------------------------------------------------------------}
procedure TProject.AddUnit(AUnit: TUnitInfo; AddToProjectFile:boolean);
var ShortUnitName:string;
UnitNameStart,UnitNameEnd:integer;
begin
if (AUnit = nil) then exit;
fUnitList.Add(AUnit);
AUnit.OnFileBackup:=@OnUnitFileBackup;
AUnit.OnLoadSaveFilename:=@OnLoadSaveFilename;
AUnit.OnUnitNameChange:=@OnUnitNameChange;
if AddToProjectFile and (MainUnit>=0) then begin
// add unit to uses section
ShortUnitName:=FindUnitNameInSource(AUnit.Source.Source,
UnitNameStart,UnitNameEnd);
if ShortUnitName='' then ShortUnitName:=AUnit.UnitName;
if (ShortUnitName<>'') then
AddToProgramUsesSection(Units[MainUnit].Source,ShortUnitName,'');
end;
Modified:=true;
end;
{------------------------------------------------------------------------------
TProject RemoveUnit
------------------------------------------------------------------------------}
procedure TProject.RemoveUnit(Index: integer);
var
OldUnitInfo: TUnitInfo;
begin
if (Index<0) or (Index>=UnitCount) then begin
writeln('ERROR: TProject.RemoveUnit index out of bounds');
Halt;
end;
if (Index=MainUnit) then begin
writeln('ERROR: TProject.RemoveUnit index = MainUnit');
Halt;
end;
OldUnitInfo:=Units[Index];
Modified:=true;
if MainUnit>=0 then begin
// remove unit from uses section and from createforms in program file
if OldUnitInfo.UnitName<>'' then
RemoveFromProgramUsesSection(Units[MainUnit].Source,OldUnitInfo.UnitName);
if (OldUnitInfo.FormName<>'') and (RemoveCreateFormFromProjectFile(
'T'+OldUnitInfo.FormName,OldUnitInfo.FormName)) then
Units[MainUnit].Source.Modified:=true;
end;
// delete bookmarks on this unit
if OldUnitInfo.EditorIndex>=0 then begin
Bookmarks.DeleteAllWithEditorIndex(OldUnitInfo.EditorIndex);
end;
// delete unitinfo instance
OldUnitInfo.Free;
fUnitList.Delete(Index);
end;
{------------------------------------------------------------------------------
TProject Clear
------------------------------------------------------------------------------}
procedure TProject.Clear;
var i:integer;
begin
if XMLCfg<>nil then XMLCfg.Free;
XMLCfg:=nil;
for i:=0 to UnitCount-1 do Units[i].Free;
fUnitList.Clear;
fActiveEditorIndexAtStart := -1;
fBookmarks.Clear;
fCompilerOptions.Clear;
fIconPath := '';
fMainUnit := -1;
fModified := false;
fOutputDirectory := '.';
fProjectFile := '';
fTargetFileExt := '';
fTitle := '';
fUnitOutputDirectory := '.';
end;
function TProject.GetUnits(Index:integer):TUnitInfo;
begin
Result:=TUnitInfo(fUnitList[Index]);
end;
procedure TProject.SetUnits(Index:integer; AUnitInfo: TUnitInfo);
begin
fUnitList[Index]:=AUnitInfo;
Modified:=true;
end;
function TProject.UnitCount:integer;
begin
Result:=fUnitList.Count;
end;
function TProject.NewUniqueUnitName:string;
function ExpandedUnitname(AnUnitName:string):string;
var s:string;
begin
if ExtractFilePath(AnUnitName)<>'' then
Result:=AnUnitName
else begin
s:=ExtractFilePath(fProjectFile);
if s<>'' then
Result:=s+AnUnitName
else
Result:=GetCurrentDir+OSDirSeparator+AnUnitName;
end;
Result:=lowercase(ChangeFileExt(Result,''));
end;
function UnitNameExists(AnUnitName:string):boolean;
var i:integer;
ExpName:string;
begin
Result:=true;
ExpName:=ExpandedUnitName(AnUnitName);
if ExpandedUnitname(fProjectFile)=Expname then exit;
for i:=0 to UnitCount-1 do
if (Units[i].UnitName<>'') and (Units[i].IsPartOfProject)
and (ExpandedUnitName(Units[i].UnitName)=ExpName) then
exit;
Result:=false;
end;
// NewUniqueUnitName
var u:integer;
begin
u:=1;
while (UnitNameExists('Unit'+IntToStr(u))) do inc(u);
Result:='Unit'+IntToStr(u);
end;
function TProject.AddCreateFormToProjectFile(AClassName,AName:string):boolean;
begin
Result:=AddCreateFormToProgram(Units[MainUnit].Source,AClassName,AName);
if Result then Modified:=true;
end;
function TProject.RemoveCreateFormFromProjectFile(
AClassName,AName:string):boolean;
begin
Result:=RemoveCreateFormFromProgram(Units[MainUnit].Source,AClassName,AName);
if Result then Modified:=true;
end;
function TProject.FormIsCreatedInProjectFile(AClassname,AName:string):boolean;
begin
Result:=CreateFormExistsInProgram(Units[MainUnit].Source.Source,AClassName,AName);
end;
function TProject.IndexOfUnitWithName(AUnitName:string;
OnlyProjectUnits:boolean):integer;
begin
Result:=UnitCount-1;
while (Result>=0) do begin
if (OnlyProjectUnits and Units[Result].IsPartOfProject)
or (not OnlyProjectUnits) then begin
if (lowercase(Units[Result].UnitName)=lowercase(AUnitName)) then
exit;
end;
dec(Result);
end;
end;
function TProject.IndexOfUnitWithForm(AForm: TComponent;
OnlyProjectUnits:boolean):integer;
begin
Result:=UnitCount-1;
while (Result>=0) do begin
if (OnlyProjectUnits and Units[Result].IsPartOfProject)
or (not OnlyProjectUnits) then begin
if Units[Result].Form=AForm then
exit;
end;
dec(Result);
end;
end;
function TProject.UnitWithEditorIndex(Index:integer):TUnitInfo;
var i:integer;
begin
i:=UnitCount-1;
while (i>=0) and (Units[i].EditorIndex<>Index) do dec(i);
if i>=0 then
Result:=Units[i]
else
Result:=nil;
end;
function TProject.UnitIsUsed(AUnitName:string):boolean;
begin
Result:=UnitIsUsedInSource(Units[MainUnit].Source.Source,AUnitName);
end;
function TProject.GetResourceFilename(AnUnitInfo: TUnitInfo;
Index:integer):string;
var
IncludeStart,IncludeEnd:integer;
IncludeDirective,IncludeFilename:string;
begin
// find the first include filename in the intialization section
if FindIncludeDirective(AnUnitInfo.Source.Source,'initialization'
,Index,IncludeStart,IncludeEnd)
then begin
SplitCompilerDirective(copy(AnUnitInfo.Source.Source
,IncludeStart,IncludeEnd-IncludeStart)
,IncludeDirective,IncludeFilename);
Result:=IncludeFilename;
end else
Result:='';
end;
function TProject.SearchIncludeFile(AnUnitInfo: TUnitInfo;
Filename:string):string;
begin
if ExtractFileExt(Filename)='' then Filename:=Filename+'.pp';
// search in the unit directory
Result:=ExtractFilePath(AnUnitInfo.Filename)+Filename;
if FileExists(Result) then exit;
// search in all include paths
Result:=SearchFile(Filename,CompilerOptions.IncludeFiles
,ExtractFilePath(AnUnitInfo.Filename));
end;
function TProject.SearchFile(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)]<>OSDirSeparator then
CurPath:=CurPath+OSDirSeparator;
Result:=CurPath+Filename;
if FileExists(Result) then exit;
end;
StartPos:=EndPos+1;
end;
finally
SetCurrentDir(OldDir);
end;
Result:='';
end;
function TProject.SearchResourceFilename(AnUnitInfo: TUnitInfo):string;
var s:string;
begin
Result:=GetResourceFilename(AnUnitInfo,1);
if Result='' then begin
Result:=ChangeFileExt(AnUnitInfo.Filename,ResourceFileExt);
exit;
end;
if ExtractFileExt(Result)='' then Result:=Result+'.pp';
s:=ExtractFilePath(AnUnitInfo.Filename)+Result;
if FileExists(s) then begin
Result:=s;
exit;
end;
if Result<>'' then
SearchIncludeFile(AnUnitInfo,Result);
if Result='' then
Result:=ChangeFileExt(AnUnitInfo.Filename,ResourceFileExt);
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;
begin
for i:=0 to UnitCount-1 do begin
if Units[i].EditorIndex=EditorIndex then
Units[i].EditorIndex:=-1
else if Units[i].EditorIndex>EditorIndex then
Units[i].EditorIndex:=Units[i].EditorIndex-1;
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);
var i:integer;
begin
for i:=0 to UnitCount-1 do begin
if Units[i].EditorIndex>=EditorIndex then
Units[i].EditorIndex:=Units[i].EditorIndex+1;
end;
i:=Bookmarks.Count-1;
while (i>=0) do begin
if (Bookmarks[i].EditorIndex>=EditorIndex) then
Bookmarks[i].EditorIndex:=Bookmarks[i].EditorIndex+1;
dec(i);
end;
Modified:=true;
end;
procedure TProject.SetProjectFile(NewProjectFilename: string);
var NewProgramName,Ext:string;
begin
DoDirSeparators(NewProjectFilename);
NewProjectFilename:=ExpandFilename(NewProjectFilename);
if NewProjectFilename=fProjectFile then exit;
Ext:=ExtractFileExt(NewProjectFilename);
if ProjectType in [ptProgram, ptApplication] then begin
// change programname in source
NewProgramName:=ExtractFilename(NewProjectFilename);
NewProgramName:=copy(NewProgramName,1,length(NewProgramName)-length(Ext));
if MainUnit>=0 then
RenameProgramInSource(Units[MainUnit].Source,NewProgramName);
end;
if MainUnit>=0 then begin
Units[MainUnit].Filename:=ChangeFileExt(NewProjectFilename
,ProjectDefaultExt[ProjectType]);
Units[MainUnit].Modified:=true;
end;
fProjectFile:=NewProjectFilename;
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;
function TProject.GetProjectInfoFile:string;
begin
Result:=fProjectFile;
if Result<>'' then Result:=ChangeFileExt(Result,'.lpi');
end;
procedure TProject.SetProjectInfoFile(NewFilename:string);
begin
if NewFilename='' then exit;
NewFilename:=ChangeFileExt(NewFilename,ProjectDefaultExt[ProjectType]);
ProjectFile:=NewFilename;
end;
procedure TProject.OnLoadSaveFilename(var AFilename:string; Load:boolean);
var ProjectPath:string;
begin
ProjectPath:=ExtractFilePath(ProjectFile);
if ProjectPath='' then ProjectPath:=GetCurrentDir;
DoDirSeparators(AFilename);
if Load then begin
// make filename absolute
if not FilenameIsAbsolute(AFilename) then
AFilename:=ProjectPath+AFilename;
end else begin
// try making filename relative to project file
if FilenameIsAbsolute(AFilename)
and (copy(AFilename,1,length(ProjectPath))=ProjectPath) then
AFilename:=copy(AFilename,length(ProjectPath)+1,
length(AFilename)-length(ProjectPath));
end;
end;
procedure TProject.OnUnitNameChange(AnUnitInfo: TUnitInfo;
const OldUnitName, NewUnitName: string; var Allowed: boolean);
var i:integer;
begin
if AnUnitInfo.IsPartOfProject then begin
// check if no other project unit has this name
for i:=0 to UnitCount-1 do
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;
if ProjectType in [ptProgram, ptApplication] then begin
// rename unit in program uses section
RenameUnitInProgramUsesSection(Units[MainUnit].Source
,OldUnitName,NewUnitName,'');
end;
end;
end;
function TProject.SomethingModified: boolean;
var i: integer;
begin
Result:=Modified;
for i:=0 to UnitCount-1 do Result:=Result or Units[i].Modified;
end;
end.
{
$Log$
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
Revision 1.14 2000/07/09 20:18:55 lazarus
MWE:
+ added new controlselection
+ some fixes
~ some cleanup
Revision 1.13 2000/05/10 02:34:43 lazarus
Changed writelns to Asserts except for ERROR and WARNING messages. CAW
Revision 1.12 2000/04/18 20:06:39 lazarus
Added some functions to Compiler.pp
Revision 1.11 2000/04/17 19:50:05 lazarus
Added some compiler stuff built into Lazarus.
This depends on the path to your compiler being correct in the compileroptions
dialog.
Shane
Revision 1.10 2000/03/07 16:52:58 lazarus
Fixxed a problem with the main.pp unit determining a new files FORM name.
Shane
Revision 1.9 2000/03/03 20:22:02 lazarus
Trying to add TBitBtn
Shane
Revision 1.8 2000/03/01 21:54:05 lazarus
90% finished with SAVE PROJECT and OPEN PROJECT
Shane
Revision 1.6 1999/05/14 18:44:17 lazarus
*** empty log message ***
Revision 1.5 1999/05/14 14:53:10 michael
+ Removed objpas from uses clause
Revision 1.4 1999/05/14 14:39:44 michael
All file stuff now uses sysutils. Win32 compiles
Revision 1.3 1999/05/07 05:46:54 lazarus
*** empty log message ***
Revision 1.2 1999/04/28 05:29:37 lazarus
*** empty log message ***
Revision 1.1 1999/04/27 05:08:28 lazarus
*** empty log message ***
Revision 1.3 1999/04/20 02:56:42 lazarus
*** empty log message ***
Revision 1.2 1999/04/18 05:42:05 lazarus
*** empty log message ***
Revision 1.1 1999/04/14 07:31:44 michael
+ Initial implementation
}