mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-27 18:53:48 +02:00
402 lines
9.7 KiB
ObjectPascal
402 lines
9.7 KiB
ObjectPascal
unit IDETemplateProject;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils, StrUtils, ContNrs,
|
|
// LCL
|
|
LResources, Forms, Controls, Graphics, Dialogs,
|
|
// LazUtils
|
|
LazFileUtils, LazLoggerBase,
|
|
// IdeIntf
|
|
ProjectIntf, NewItemIntf, MenuIntf, BaseIDEIntf, LazIDEIntf,
|
|
// ProjectTemplates
|
|
ProjectTemplates, frmTemplateSettings, frmTemplateVariables, ptstrconst;
|
|
|
|
type
|
|
|
|
{ TTemplateProjectDescriptor }
|
|
|
|
TTemplateProjectDescriptor = class(TProjectDescriptor)
|
|
Private
|
|
FTemplate : TProjectTemplate;
|
|
FProjectDirectory : String;
|
|
FProjectName : String;
|
|
FIgnoreExts,
|
|
FVariables : TStrings;
|
|
Function ShowOptionsDialog : TModalResult;
|
|
public
|
|
constructor Create(ATemplate : TProjectTemplate); overload;
|
|
destructor Destroy; override;
|
|
Function DoInitDescriptor : TModalResult; override;
|
|
function GetLocalizedName: string; override;
|
|
function GetLocalizedDescription: string; override;
|
|
function InitProject(AProject: TLazProject) : TModalResult; override;
|
|
function CreateStartFiles({%H-}AProject: TLazProject) : TModalResult; override;
|
|
Property Template : TProjectTemplate Read FTemplate Write FTemplate;
|
|
end;
|
|
|
|
procedure Register;
|
|
|
|
implementation
|
|
|
|
Var
|
|
IDETemplates : TProjectTemplates = nil;
|
|
itmFileNewFromTemplate : TIDEMenuSection;
|
|
MenuList : TObjectList;
|
|
|
|
Type
|
|
{ TIDEObject }
|
|
|
|
TIDEObject=Class(TObject)
|
|
FProjDesc : TTemplateProjectDescriptor;
|
|
FProjMenu : TIDEMenuCommand;
|
|
Constructor Create(AProjDesc : TTemplateProjectDescriptor;
|
|
AProjMenu : TIDEMenuCommand);
|
|
end;
|
|
|
|
{ TIDEObject }
|
|
|
|
constructor TIDEObject.Create(AProjDesc: TTemplateProjectDescriptor;
|
|
AProjMenu: TIDEMenuCommand);
|
|
|
|
begin
|
|
FPRojDesc:=AProjDesc;
|
|
FPRojMenu:=AProjMenu;
|
|
end;
|
|
|
|
Const
|
|
STemplateSettings = 'itmTemplateSettings';
|
|
SItmtemplate = 'itmTemplate';
|
|
|
|
{ ---------------------------------------------------------------------
|
|
Configuration
|
|
---------------------------------------------------------------------}
|
|
|
|
Function GetTemplateDir : String;
|
|
|
|
begin
|
|
With GetIDEConfigStorage('projtemplate.xml',True) do
|
|
try
|
|
Result:=GetValue('TemplateDir',AppendPathDelim(LazarusIDE.GetPrimaryConfigPath)+'templates');
|
|
Finally
|
|
Free;
|
|
end;
|
|
end;
|
|
|
|
procedure SaveTemplateSettings;
|
|
|
|
begin
|
|
With GetIDEConfigStorage('projtemplate.xml',False) do
|
|
try
|
|
SetValue('TemplateDir',IDETemplates.TemplateDir);
|
|
WriteToDisk;
|
|
Finally
|
|
Free;
|
|
end;
|
|
end;
|
|
|
|
{ ---------------------------------------------------------------------
|
|
Registration
|
|
---------------------------------------------------------------------}
|
|
|
|
Procedure RegisterTemplateCategory;
|
|
|
|
begin
|
|
NewIDEItems.Add(TNewIDEItemCategory.Create(STemplateCategory));
|
|
end;
|
|
|
|
procedure FileReplaceText(FN, AFrom, ATo: string);
|
|
var
|
|
sl: TStringList;
|
|
i: Integer;
|
|
begin
|
|
//DebugLn(['FileReplaceText: From=', AFrom, ', To=', ATo]);
|
|
if (not FileExistsUTF8(FN)) or (AFrom='') then
|
|
exit;
|
|
sl:=TStringList.Create;
|
|
try
|
|
sl.LoadFromFile(FN);
|
|
for i:=0 to sl.Count-1 do
|
|
sl[i]:=ReplaceText(sl[i],AFrom,ATo);
|
|
sl.SaveToFile(fn);
|
|
finally
|
|
sl.Free;
|
|
end;
|
|
end;
|
|
|
|
Procedure DoProject(Sender : TObject);
|
|
|
|
Var
|
|
I : Integer;
|
|
Desc : TTemplateProjectDescriptor;
|
|
fn: string;
|
|
|
|
begin
|
|
I:=MenuList.count-1;
|
|
Desc:=Nil;
|
|
While (Desc=Nil) and (I>=0) do
|
|
begin
|
|
With TIDEObject(MenuList[i]) do
|
|
if FProjMenu=Sender then
|
|
Desc:=FProjDesc;
|
|
Dec(i);
|
|
end;
|
|
If Desc=Nil then
|
|
exit;
|
|
|
|
If Desc.ShowOptionsDialog<>mrOk then
|
|
exit;
|
|
Desc.Template.CreateProject(Desc.FProjectDirectory,Desc.FVariables);
|
|
fn:=Desc.FProjectDirectory+Desc.FProjectName;
|
|
FileReplaceText(fn+'.lpi',Desc.FTemplate.ProjectFile,Desc.FProjectName);
|
|
FileReplaceText(fn+'.lpr',Desc.FTemplate.ProjectFile,Desc.FProjectName);
|
|
FileReplaceText(fn+'.lps',Desc.FTemplate.ProjectFile,Desc.FProjectName);
|
|
LazarusIDE.DoOpenProjectFile(Desc.FProjectDirectory+Desc.FProjectName+'.lpi',
|
|
[ofProjectLoading,ofOnlyIfExists,ofConvertMacros,ofDoLoadResource]);
|
|
end;
|
|
|
|
procedure RegisterKnowntemplates;
|
|
|
|
Var
|
|
I : Integer;
|
|
ATemplate : TProjectTemplate;
|
|
ProjDesc : TTemplateProjectDescriptor;
|
|
ProjMenu : TIDEMenuCommand;
|
|
|
|
begin
|
|
For I:=0 to IDETemplates.Count-1 do
|
|
begin
|
|
ATemplate:=IDETemplates[i];
|
|
ProjDesc:=TTemplateProjectDescriptor.Create(ATemplate);
|
|
RegisterProjectDescriptor(ProjDesc,STemplateCategory);
|
|
ProjMenu:=RegisterIDEMenuCommand(itmFileNewFromTemplate,
|
|
SItmtemplate+ATemplate.Name,
|
|
ATemplate.Name,
|
|
Nil,@DoProject,Nil);
|
|
MenuList.Add(TIDEObject.Create(ProjDesc,ProjMenu));
|
|
end;
|
|
end;
|
|
|
|
procedure UnRegisterKnownTemplates;
|
|
|
|
Var
|
|
I : Integer;
|
|
|
|
begin
|
|
For I:=MenuList.Count-1 downto 0 do
|
|
begin
|
|
With TIDEObject(MenuList[i]) do
|
|
begin
|
|
ProjectDescriptors.UnregisterDescriptor(FProjDesc);
|
|
FreeAndNil(FProjMenu);
|
|
end;
|
|
MenuList.Delete(I);
|
|
end;
|
|
end;
|
|
|
|
procedure ChangeSettings(Sender : TObject);
|
|
|
|
begin
|
|
With TTemplateSettingsForm.Create(Application) do
|
|
Try
|
|
Templates:=IDETemplates;
|
|
if ShowModal=mrOK then
|
|
begin
|
|
SaveTemplateSettings;
|
|
UnRegisterKnownTemplates;
|
|
RegisterKnownTemplates;
|
|
end;
|
|
Finally
|
|
Free;
|
|
end;
|
|
end;
|
|
|
|
procedure Register;
|
|
|
|
begin
|
|
RegisterIdeMenuCommand(itmOptionsDialogs,STemplateSettings,SProjectTemplateSettings,nil,@ChangeSettings);
|
|
itmFileNewFromTemplate:=RegisterIDESubMenu(itmFileNew,
|
|
'itmFileFromTemplate',
|
|
SNewFromTemplate);
|
|
IDETemplates:=TProjectTemplates.Create(GetTemplateDir);
|
|
RegisterTemplateCategory;
|
|
RegisterKnownTemplates;
|
|
end;
|
|
|
|
|
|
{ TTemplateProjectDescriptor }
|
|
|
|
function TTemplateProjectDescriptor.ShowOptionsDialog : TModalResult;
|
|
|
|
var
|
|
I: Integer;
|
|
|
|
begin
|
|
With TProjectVariablesForm.Create(Application) do
|
|
try
|
|
Caption:=Caption+' '+FTemplate.Name;
|
|
FVariables.Assign(FTemplate.Variables);
|
|
I:=FVariables.IndexOfName('ProjName');
|
|
if (I<>-1) then
|
|
begin
|
|
EProjectName.Text:=FVariables.Values['ProjName'];
|
|
FVariables.Delete(I);
|
|
end;
|
|
I:=FVariables.IndexOfName('ProjDir');
|
|
if (I<>-1) then
|
|
begin
|
|
DEDestDir.Text:=FVariables.Values['ProjDir'];
|
|
FVariables.Delete(I);
|
|
end;
|
|
Templates:=Templates;
|
|
Variables:=FVariables;
|
|
Result:=ShowModal;
|
|
if Result=mrOK then
|
|
begin
|
|
FProjectDirectory:=IncludeTrailingPathDelimiter(ProjectDir);
|
|
FProjectName:=ProjectName;
|
|
FVariables.Values['ProjName']:=FProjectName;
|
|
FVariables.Values['ProjDir']:=FProjectDirectory;
|
|
end;
|
|
finally
|
|
Free;
|
|
end;
|
|
end;
|
|
|
|
|
|
constructor TTemplateProjectDescriptor.Create(ATemplate : TProjectTemplate);
|
|
begin
|
|
inherited Create;
|
|
FTemplate:=ATemplate;
|
|
If Assigned(FTemplate) then
|
|
Name:=FTemplate.Name
|
|
else
|
|
Name:='Template Project';
|
|
FVariables:=TStringList.Create;
|
|
FIgnoreExts:=TStringList.Create;
|
|
{$IF FPC_FULLVERSION>=30200}FIgnoreExts.UseLocale := false;{$ENDIF}
|
|
FIgnoreExts.CommaText:='.lpr,.lps,.lfm,.lrs,.ico,.res,.lpi,.bak';
|
|
end;
|
|
|
|
destructor TTemplateProjectDescriptor.destroy;
|
|
begin
|
|
FreeAndNil(FIgnoreExts);
|
|
FTemplate:=Nil;
|
|
FreeAndNil(FVariables);
|
|
Inherited;
|
|
end;
|
|
|
|
|
|
function TTemplateProjectDescriptor.GetLocalizedName: string;
|
|
begin
|
|
Result:=FTemplate.Name;
|
|
end;
|
|
|
|
function TTemplateProjectDescriptor.GetLocalizedDescription: string;
|
|
begin
|
|
Result:=FTemplate.Description;
|
|
end;
|
|
|
|
|
|
function TTemplateProjectDescriptor.DoInitDescriptor: TModalResult;
|
|
var
|
|
I : integer;
|
|
Desc : TTemplateProjectDescriptor;
|
|
begin
|
|
Result:=mrCancel;
|
|
I:=MenuList.count-1;
|
|
Desc:=Nil;
|
|
While (Desc=Nil) and (I>=0) do
|
|
begin
|
|
With TIDEObject(MenuList[i]) do
|
|
if FProjDesc=self then
|
|
begin
|
|
DoProject(FProjMenu);
|
|
exit;
|
|
end;
|
|
Dec(i);
|
|
end;
|
|
end;
|
|
|
|
|
|
function TTemplateProjectDescriptor.InitProject(AProject: TLazProject) : TModalResult;
|
|
|
|
Var
|
|
I : Integer;
|
|
AFile: TLazProjectFile;
|
|
FN : String;
|
|
L : TStringList;
|
|
|
|
begin
|
|
AProject.AddPackageDependency('FCL');
|
|
AProject.AddPackageDependency('LCL');
|
|
AProject.Title:=FProjectName;
|
|
AProject.UseAppBundle:=true;
|
|
AProject.UseManifest:=true;
|
|
AProject.LoadDefaultIcon;
|
|
If Assigned(FTemplate) then
|
|
begin
|
|
FTemplate.CreateProjectDirs(FProjectDirectory,FVariables);
|
|
AProject.ProjectInfoFile:=FProjectDirectory+FProjectName+'.lpi';
|
|
For I:=0 to FTemplate.FileCount-1 do
|
|
begin
|
|
FN:=FTemplate.FileNames[I];
|
|
If FilenameExtIs(FN,'lpr') then
|
|
begin
|
|
FN:=FProjectDirectory+FTemplate.TargetFileName(FN,FVariables);
|
|
AFile:=AProject.CreateProjectFile(FN);
|
|
AFile.IsPartOfProject:=true;
|
|
AProject.AddFile(AFile,False);
|
|
AProject.MainFileID:=0;
|
|
L:=TStringList.Create;
|
|
try
|
|
FTemplate.CreateFile(I,L,FVariables);
|
|
AFile.SetSourceText(L.Text);
|
|
Finally
|
|
L.Free;
|
|
end;
|
|
end;
|
|
end;
|
|
Result:=mrOK;
|
|
end
|
|
else
|
|
Result:=mrCancel;
|
|
|
|
Result:=mrCancel;
|
|
|
|
end;
|
|
|
|
Function TTemplateProjectDescriptor.CreateStartFiles(AProject: TLazProject) : TModalresult;
|
|
|
|
Var
|
|
I : Integer;
|
|
FN : String;
|
|
|
|
begin
|
|
if Assigned(FTemplate) then
|
|
begin
|
|
Result:=mrOK;
|
|
For I:=0 to FTemplate.FileCount-1 do
|
|
begin
|
|
FN:=FTemplate.FileNames[I];
|
|
If (FIgnoreExts.IndexOf(ExtractFileExt(FN))=-1) then
|
|
begin
|
|
FN:=FProjectDirectory+FTemplate.TargetFileName(FN,FVariables);
|
|
LazarusIDE.DoOpenEditorFile(FN, -1, -1, [ofProjectLoading,ofQuiet,ofAddToProject]);
|
|
end;
|
|
end;
|
|
end
|
|
else
|
|
Result:=mrCancel;
|
|
end;
|
|
|
|
Initialization
|
|
MenuList:=TObjectList.Create;
|
|
Finalization
|
|
FreeAndNil(IDETemplates);
|
|
FreeAndNil(MenuList);
|
|
end.
|