1 unit ProjectDescriptors;
2 
3 {$mode objfpc}{$H+}
4 
5 interface
6 
7 uses
8   Classes, SysUtils,
9   // LCL
10   Controls, Forms,
11   // Codetools
12   FileProcs,
13   // LazUtils
14   LazFileUtils, LazUTF8,
15   // IdeIntf
16   CompOptsIntf, ProjectIntf, LazIDEIntf,
17   // IDE
18   frmCustomApplicationOptions, LazarusIDEStrConsts, Project, W32Manifest;
19 
20 type
21 
22   //----------------------------------------------------------------------------
23 
24   { TProjectApplicationDescriptor }
25 
26   TProjectApplicationDescriptor = class(TProjectDescriptor)
27   public
28     constructor Create; override;
GetLocalizedNamenull29     function GetLocalizedName: string; override;
GetLocalizedDescriptionnull30     function GetLocalizedDescription: string; override;
InitProjectnull31     function InitProject(AProject: TLazProject): TModalResult; override;
CreateStartFilesnull32     function CreateStartFiles({%H-}AProject: TLazProject): TModalResult; override;
33   end;
34 
35   { TProjectSimpleProgramDescriptor }
36 
37   TProjectSimpleProgramDescriptor = class(TProjectDescriptor)
38   public
39     constructor Create; override;
GetLocalizedNamenull40     function GetLocalizedName: string; override;
GetLocalizedDescriptionnull41     function GetLocalizedDescription: string; override;
InitProjectnull42     function InitProject(AProject: TLazProject): TModalResult; override;
CreateStartFilesnull43     function CreateStartFiles(AProject: TLazProject): TModalResult; override;
44   end;
45 
46   { TProjectProgramDescriptor }
47 
48   TProjectProgramDescriptor = class(TProjectDescriptor)
49   public
50     constructor Create; override;
GetLocalizedNamenull51     function GetLocalizedName: string; override;
GetLocalizedDescriptionnull52     function GetLocalizedDescription: string; override;
InitProjectnull53     function InitProject(AProject: TLazProject): TModalResult; override;
CreateStartFilesnull54     function CreateStartFiles(AProject: TLazProject): TModalResult; override;
55   end;
56 
57   { TProjectConsoleApplicationDescriptor }
58 
59   TProjectConsoleApplicationDescriptor = class(TProjectDescriptor)
60   public
61     constructor Create; override;
GetLocalizedNamenull62     function GetLocalizedName: string; override;
GetLocalizedDescriptionnull63     function GetLocalizedDescription: string; override;
InitProjectnull64     function InitProject(AProject: TLazProject): TModalResult; override;
CreateStartFilesnull65     function CreateStartFiles(AProject: TLazProject): TModalResult; override;
66   end;
67 
68   { TProjectLibraryDescriptor }
69 
70   TProjectLibraryDescriptor = class(TProjectDescriptor)
71   public
72     constructor Create; override;
GetLocalizedNamenull73     function GetLocalizedName: string; override;
GetLocalizedDescriptionnull74     function GetLocalizedDescription: string; override;
InitProjectnull75     function InitProject(AProject: TLazProject): TModalResult; override;
CreateStartFilesnull76     function CreateStartFiles(AProject: TLazProject): TModalResult; override;
77   end;
78 
79   { TProjectManualProgramDescriptor }
80 
81   TProjectManualProgramDescriptor = class(TProjectDescriptor)
82   private
83     FAddMainSource: boolean;
84   public
85     constructor Create; override;
GetLocalizedNamenull86     function GetLocalizedName: string; override;
GetLocalizedDescriptionnull87     function GetLocalizedDescription: string; override;
InitProjectnull88     function InitProject(AProject: TLazProject): TModalResult; override;
CreateStartFilesnull89     function CreateStartFiles(AProject: TLazProject): TModalResult; override;
90     property AddMainSource: boolean read FAddMainSource write FAddMainSource;
91   end;
92 
93   { TProjectEmptyProgramDescriptor }
94 
95   TProjectEmptyProgramDescriptor = class(TProjectManualProgramDescriptor)
96   public
97     constructor Create; override;
98   end;
99 
100 
101 implementation
102 
103 { TProjectApplicationDescriptor }
104 
105 constructor TProjectApplicationDescriptor.Create;
106 begin
107   inherited Create;
108   Name:=ProjDescNameApplication;
109   Flags:=Flags+[pfUseDefaultCompilerOptions];
110 end;
111 
TProjectApplicationDescriptor.GetLocalizedNamenull112 function TProjectApplicationDescriptor.GetLocalizedName: string;
113 begin
114   Result:=dlgPOApplication;
115 end;
116 
GetLocalizedDescriptionnull117 function TProjectApplicationDescriptor.GetLocalizedDescription: string;
118 begin
119   Result := GetLocalizedName + LineEnding+LineEnding + lisApplicationProgramDescriptor;
120 end;
121 
InitProjectnull122 function TProjectApplicationDescriptor.InitProject(AProject: TLazProject): TModalResult;
123 var
124   NewSource: String;
125   MainFile: TLazProjectFile;
126 begin
127   Result:=inherited InitProject(AProject);
128 
129   MainFile:=AProject.CreateProjectFile('project1.lpr');
130   MainFile.IsPartOfProject:=true;
131   AProject.AddFile(MainFile,false);
132   AProject.MainFileID:=0;
133   AProject.UseAppBundle:=true;
134   AProject.UseManifest:=true;
135   AProject.Scaled:=true;
136   (AProject as TProject).ProjResources.XPManifest.DpiAware := xmdaTrue;
137   AProject.LoadDefaultIcon;
138 
139   // create program source
140   NewSource:='program Project1;'+LineEnding
141     +LineEnding
142     +'{$mode objfpc}{$H+}'+LineEnding
143     +LineEnding
144     +'uses'+LineEnding
145     +'  {$IFDEF UNIX}{$IFDEF UseCThreads}'+LineEnding
146     +'  cthreads,'+LineEnding
147     +'  {$ENDIF}{$ENDIF}'+LineEnding
148     +'  Interfaces, // this includes the LCL widgetset'+LineEnding
149     +'  Forms'+LineEnding
150     +'  { you can add units after this };'+LineEnding
151     +LineEnding
152     +'begin'+LineEnding
153     +'  RequireDerivedFormResource:=True;'+LineEnding
154     +'  Application.Scaled:=True;'+LineEnding
155     +'  Application.Initialize;'+LineEnding
156     +'  Application.Run;'+LineEnding
157     +'end.'+LineEnding
158     +LineEnding;
159   AProject.MainFile.SetSourceText(NewSource,true);
160 
161   // add lcl pp/pas dirs to source search path
162   AProject.AddPackageDependency('LCL');
163   AProject.LazCompilerOptions.Win32GraphicApp:=true;
164   AProject.LazCompilerOptions.UnitOutputDirectory:='lib'+PathDelim+'$(TargetCPU)-$(TargetOS)';
165   AProject.LazCompilerOptions.TargetFilename:='project1';
166 end;
167 
TProjectApplicationDescriptor.CreateStartFilesnull168 function TProjectApplicationDescriptor.CreateStartFiles(AProject: TLazProject
169   ): TModalResult;
170 begin
171   Result:=LazarusIDE.DoNewEditorFile(FileDescriptorForm,'','',
172                          [nfIsPartOfProject,nfOpenInEditor,nfCreateDefaultSrc]);
173 end;
174 
175 { TProjectSimpleProgramDescriptor }
176 
177 constructor TProjectSimpleProgramDescriptor.Create;
178 begin
179   inherited Create;
180   Name:=ProjDescNameSimpleProgram;
181   Flags:=Flags-[pfMainUnitHasCreateFormStatements,pfMainUnitHasTitleStatement,pfMainUnitHasScaledStatement]
182               +[pfUseDefaultCompilerOptions];
183 end;
184 
GetLocalizedNamenull185 function TProjectSimpleProgramDescriptor.GetLocalizedName: string;
186 begin
187   Result:=lisSimpleProgram;
188 end;
189 
GetLocalizedDescriptionnull190 function TProjectSimpleProgramDescriptor.GetLocalizedDescription: string;
191 begin
192   Result := GetLocalizedName + LineEnding+LineEnding + lisSimpleProgramProgramDescriptor;
193 end;
194 
InitProjectnull195 function TProjectSimpleProgramDescriptor.InitProject(AProject: TLazProject): TModalResult;
196 var
197   NewSource: String;
198   MainFile: TLazProjectFile;
199 begin
200   Result:=inherited InitProject(AProject);
201 
202   MainFile:=AProject.CreateProjectFile('project1.lpr');
203   MainFile.IsPartOfProject:=true;
204   AProject.AddFile(MainFile,false);
205   AProject.MainFileID:=0;
206 
207   // create program source
208   NewSource:='program Project1;'+LineEnding
209     +LineEnding
210     +'begin'+LineEnding
211     +'end.'+LineEnding
212     +LineEnding;
213   AProject.MainFile.SetSourceText(NewSource,true);
214 
215   AProject.LazCompilerOptions.UnitOutputDirectory:='lib'+PathDelim+'$(TargetCPU)-$(TargetOS)';
216   AProject.LazCompilerOptions.TargetFilename:='project1';
217 end;
218 
TProjectSimpleProgramDescriptor.CreateStartFilesnull219 function TProjectSimpleProgramDescriptor.CreateStartFiles(AProject: TLazProject): TModalResult;
220 begin
221   Result:=LazarusIDE.DoOpenEditorFile(AProject.MainFile.Filename,-1,-1,
222                                       [ofProjectLoading,ofRegularFile]);
223 end;
224 
225 { TProjectProgramDescriptor }
226 
227 constructor TProjectProgramDescriptor.Create;
228 begin
229   inherited Create;
230   Name:=ProjDescNameProgram;
231   Flags:=Flags-[pfMainUnitHasCreateFormStatements,pfMainUnitHasTitleStatement,pfMainUnitHasScaledStatement]
232               +[pfUseDefaultCompilerOptions];
233 end;
234 
GetLocalizedNamenull235 function TProjectProgramDescriptor.GetLocalizedName: string;
236 begin
237   Result:=lisProgram;
238 end;
239 
GetLocalizedDescriptionnull240 function TProjectProgramDescriptor.GetLocalizedDescription: string;
241 begin
242   Result := GetLocalizedName + LineEnding+LineEnding + lisProgramProgramDescriptor;
243 end;
244 
InitProjectnull245 function TProjectProgramDescriptor.InitProject(AProject: TLazProject): TModalResult;
246 var
247   NewSource: String;
248   MainFile: TLazProjectFile;
249 begin
250   Result:=inherited InitProject(AProject);
251 
252   MainFile:=AProject.CreateProjectFile('project1.lpr');
253   MainFile.IsPartOfProject:=true;
254   AProject.AddFile(MainFile,false);
255   AProject.MainFileID:=0;
256 
257   // create program source
258   NewSource:='program Project1;'+LineEnding
259     +LineEnding
260     +'{$mode objfpc}{$H+}'+LineEnding
261     +LineEnding
262     +'uses'+LineEnding
263     +'  {$IFDEF UNIX}{$IFDEF UseCThreads}'+LineEnding
264     +'  cthreads,'+LineEnding
265     +'  {$ENDIF}{$ENDIF}'+LineEnding
266     +'  Classes'+LineEnding
267     +'  { you can add units after this };'+LineEnding
268     +LineEnding
269     +'begin'+LineEnding
270     +'end.'+LineEnding
271     +LineEnding;
272   AProject.MainFile.SetSourceText(NewSource,true);
273 
274   AProject.LazCompilerOptions.UnitOutputDirectory:='lib'+PathDelim+'$(TargetCPU)-$(TargetOS)';
275   AProject.LazCompilerOptions.TargetFilename:='project1';
276 end;
277 
TProjectProgramDescriptor.CreateStartFilesnull278 function TProjectProgramDescriptor.CreateStartFiles(AProject: TLazProject): TModalResult;
279 begin
280   Result:=LazarusIDE.DoOpenEditorFile(AProject.MainFile.Filename,-1,-1,
281                                       [ofProjectLoading,ofRegularFile]);
282 end;
283 
284 { TProjectManualProgramDescriptor }
285 
286 constructor TProjectManualProgramDescriptor.Create;
287 begin
288   inherited Create;
289   VisibleInNewDialog:=false;
290   Name:=ProjDescNameCustomProgram;
291   Flags:=Flags-[pfMainUnitHasUsesSectionForAllUnits,
292                 pfMainUnitHasCreateFormStatements,
293                 pfMainUnitHasTitleStatement,
294                 pfMainUnitHasScaledStatement]
295               +[pfUseDefaultCompilerOptions];
296   FAddMainSource:=true;
297 end;
298 
TProjectManualProgramDescriptor.GetLocalizedNamenull299 function TProjectManualProgramDescriptor.GetLocalizedName: string;
300 begin
301   Result:=lisCustomProgram;
302 end;
303 
TProjectManualProgramDescriptor.GetLocalizedDescriptionnull304 function TProjectManualProgramDescriptor.GetLocalizedDescription: string;
305 begin
306   Result := GetLocalizedName + LineEnding+LineEnding + lisCustomProgramProgramDescriptor;
307 end;
308 
InitProjectnull309 function TProjectManualProgramDescriptor.InitProject(AProject: TLazProject
310   ): TModalResult;
311 var
312   NewSource: String;
313   MainFile: TLazProjectFile;
314 begin
315   Result:=inherited InitProject(AProject);
316 
317   if AddMainSource then begin
318     MainFile:=AProject.CreateProjectFile('project1.pas');
319     MainFile.IsPartOfProject:=true;
320     AProject.AddFile(MainFile,false);
321     AProject.MainFileID:=0;
322 
323     // create program source
324     NewSource:='program Project1;'+LineEnding
325       +LineEnding
326       +'{$mode objfpc}{$H+}'+LineEnding
327       +LineEnding
328       +'uses'+LineEnding
329       +'  Classes, SysUtils'+LineEnding
330       +'  { you can add units after this };'+LineEnding
331       +LineEnding
332       +'begin'+LineEnding
333       +'end.'+LineEnding
334       +LineEnding;
335     AProject.MainFile.SetSourceText(NewSource,true);
336     AProject.LazCompilerOptions.Win32GraphicApp:=false;
337   end;
338 end;
339 
TProjectManualProgramDescriptor.CreateStartFilesnull340 function TProjectManualProgramDescriptor.CreateStartFiles(AProject: TLazProject
341   ): TModalResult;
342 begin
343   if AProject.MainFile<>nil then
344     Result:=LazarusIDE.DoOpenEditorFile(AProject.MainFile.Filename,-1,-1,
345                                         [ofProjectLoading,ofRegularFile])
346   else
347     Result:=mrCancel;
348 end;
349 
350 { TProjectEmptyProgramDescriptor }
351 
352 constructor TProjectEmptyProgramDescriptor.Create;
353 begin
354   inherited Create;
355   FAddMainSource:=false;
356 end;
357 
358 { TProjectConsoleApplicationDescriptor }
359 
360 constructor TProjectConsoleApplicationDescriptor.Create;
361 begin
362   inherited Create;
363   Name:=ProjDescNameConsoleApplication;
364   Flags:=Flags-[pfMainUnitHasCreateFormStatements,pfMainUnitHasTitleStatement,pfMainUnitHasScaledStatement]
365               +[pfUseDefaultCompilerOptions];
366 end;
367 
TProjectConsoleApplicationDescriptor.GetLocalizedNamenull368 function TProjectConsoleApplicationDescriptor.GetLocalizedName: string;
369 begin
370   Result:=lisConsoleApplication;
371 end;
372 
GetLocalizedDescriptionnull373 function TProjectConsoleApplicationDescriptor.GetLocalizedDescription: string;
374 begin
375   Result := GetLocalizedName + LineEnding+LineEnding + lisConsoleApplicationProgramDescriptor;
376 end;
377 
InitProjectnull378 function TProjectConsoleApplicationDescriptor.InitProject(AProject: TLazProject
379   ): TModalResult;
380 var
381   NewSource: TStringList;
382   MainFile: TLazProjectFile;
383   C, T : String;
384   CC,CD,CU,CS, CO : Boolean;
385 
386 begin
387   Result:=inherited InitProject(AProject);
388   If Result<>mrOk then
389     Exit;
390   With TCustomApplicationOptionsForm.Create(Application) do
391     try
392       Result:=ShowModal;
393       If Result<>mrOk then
394         Exit;
395       C:=Trim(AppClassName);
396       T:=StringReplace(Title,'''','''''',[rfReplaceAll]);
397       CC:=CodeConstructor;
398       CD:=CodeDestructor;
399       CU:=CodeUsage;
400       CS:=CodeStopOnError;
401       CO:=CodeCheckOptions;
402     finally
403       Free;
404     end;
405   MainFile:=AProject.CreateProjectFile('project1.lpr');
406   MainFile.IsPartOfProject:=true;
407   AProject.AddFile(MainFile,false);
408   AProject.MainFileID:=0;
409 
410   AProject.LazCompilerOptions.UnitOutputDirectory:='lib'+PathDelim+'$(TargetCPU)-$(TargetOS)';
411   AProject.LazCompilerOptions.TargetFilename:='project1';
412   AProject.LazCompilerOptions.Win32GraphicApp:=false;
413 
414   // create program source
415   NewSource:=TStringList.Create;
416   NewSource.Add('program Project1;');
417   NewSource.Add('');
418   NewSource.Add('{$mode objfpc}{$H+}');
419   NewSource.Add('');
420   NewSource.Add('uses');
421   NewSource.Add('  {$IFDEF UNIX}{$IFDEF UseCThreads}');
422   NewSource.Add('  cthreads,');
423   NewSource.Add('  {$ENDIF}{$ENDIF}');
424   NewSource.Add('  Classes, SysUtils, CustApp');
425   NewSource.Add('  { you can add units after this };');
426   NewSource.Add('');
427   NewSource.Add('type');
428   NewSource.Add('');
429   NewSource.Add('  { '+C+' }');
430   NewSource.Add('');
431   NewSource.Add('  '+C+' = class(TCustomApplication)');
432   NewSource.Add('  protected');
433   NewSource.Add('    procedure DoRun; override;');
434   NewSource.Add('  public');
435   If CC or CS then
436     NewSource.Add('    constructor Create(TheOwner: TComponent); override;');
437   if CD then
438     NewSource.Add('    destructor Destroy; override;');
439   if CU then
440     NewSource.Add('    procedure WriteHelp; virtual;');
441   NewSource.Add('  end;');
442   NewSource.Add('');
443   NewSource.Add('{ '+C+' }');
444   NewSource.Add('');
445   NewSource.Add('procedure '+C+'.DoRun;');
446   NewSource.Add('var');
447   NewSource.Add('  ErrorMsg: String;');
448   NewSource.Add('begin');
449   if CO then
450     begin
451     NewSource.Add('  // quick check parameters');
452     NewSource.Add('  ErrorMsg:=CheckOptions(''h'',''help'');');
453     NewSource.Add('  if ErrorMsg<>'''' then begin');
454     NewSource.Add('    ShowException(Exception.Create(ErrorMsg));');
455     NewSource.Add('    Terminate;');
456     NewSource.Add('    Exit;');
457     NewSource.Add('  end;');
458     NewSource.Add('');
459     end;
460   If CU then
461     begin
462     NewSource.Add('  // parse parameters');
463     NewSource.Add('  if HasOption(''h'',''help'') then begin');
464     NewSource.Add('    WriteHelp;');
465     NewSource.Add('    Terminate;');
466     NewSource.Add('    Exit;');
467     NewSource.Add('  end;');
468     end;
469   NewSource.Add('');
470   NewSource.Add('  { add your program here }');
471   NewSource.Add('');
472   NewSource.Add('  // stop program loop');
473   NewSource.Add('  Terminate;');
474   NewSource.Add('end;');
475   NewSource.Add('');
476   If CC or CS then
477     begin
478     NewSource.Add('constructor '+C+'.Create(TheOwner: TComponent);');
479     NewSource.Add('begin');
480     NewSource.Add('  inherited Create(TheOwner);');
481     If CS then
482     NewSource.Add('  StopOnException:=True;');
483     NewSource.Add('end;');
484     NewSource.Add('');
485     end;
486   If CD then
487     begin
488     NewSource.Add('destructor '+C+'.Destroy;');
489     NewSource.Add('begin');
490     NewSource.Add('  inherited Destroy;');
491     NewSource.Add('end;');
492     NewSource.Add('');
493     end;
494   If CU then
495     begin
496     NewSource.Add('procedure '+C+'.WriteHelp;');
497     NewSource.Add('begin');
498     NewSource.Add('  { add your help code here }');
499     NewSource.Add('  writeln(''Usage: '',ExeName,'' -h'');');
500     NewSource.Add('end;');
501     NewSource.Add('');
502     end;
503   NewSource.Add('var');
504   NewSource.Add('  Application: '+C+';');
505   NewSource.Add('begin');
506   NewSource.Add('  Application:='+C+'.Create(nil);');
507   If (T<>'') then
508     begin
509     AProject.Flags:=AProject.Flags+[pfMainUnitHasTitleStatement];
510     AProject.Title:=T;
511     NewSource.Add('  Application.Title:='''+T+''';');
512     end;
513   NewSource.Add('  Application.Run;');
514   NewSource.Add('  Application.Free;');
515   NewSource.Add('end.');
516   NewSource.Add('');
517   AProject.MainFile.SetSourceText(NewSource.Text,true);
518   NewSource.Free;
519 end;
520 
TProjectConsoleApplicationDescriptor.CreateStartFilesnull521 function TProjectConsoleApplicationDescriptor.CreateStartFiles(
522   AProject: TLazProject): TModalResult;
523 begin
524   Result:=LazarusIDE.DoOpenEditorFile(AProject.MainFile.Filename,-1,-1,
525                                       [ofProjectLoading,ofRegularFile]);
526 end;
527 
528 { TProjectLibraryDescriptor }
529 
530 constructor TProjectLibraryDescriptor.Create;
531 begin
532   inherited Create;
533   Name:=ProjDescNameLibrary;
534   Flags:=Flags-[pfMainUnitHasCreateFormStatements,pfMainUnitHasTitleStatement,pfMainUnitHasScaledStatement]
535               +[pfUseDefaultCompilerOptions];
536 end;
537 
TProjectLibraryDescriptor.GetLocalizedNamenull538 function TProjectLibraryDescriptor.GetLocalizedName: string;
539 begin
540   Result:=lisPckOptsLibrary;
541 end;
542 
GetLocalizedDescriptionnull543 function TProjectLibraryDescriptor.GetLocalizedDescription: string;
544 begin
545   Result := GetLocalizedName + LineEnding+LineEnding + lisLibraryProgramDescriptor;
546 end;
547 
InitProjectnull548 function TProjectLibraryDescriptor.InitProject(AProject: TLazProject): TModalResult;
549 var
550   NewSource: String;
551   MainFile: TLazProjectFile;
552 begin
553   Result:=inherited InitProject(AProject);
554 
555   MainFile:=AProject.CreateProjectFile('project1.lpr');
556   MainFile.IsPartOfProject:=true;
557   AProject.AddFile(MainFile,false);
558   AProject.MainFileID:=0;
559   AProject.LazCompilerOptions.ExecutableType:=cetLibrary;
560 
561   // create program source
562   NewSource:='library Project1;'+LineEnding
563     +LineEnding
564     +'{$mode objfpc}{$H+}'+LineEnding
565     +LineEnding
566     +'uses'+LineEnding
567     +'  Classes'+LineEnding
568     +'  { you can add units after this };'+LineEnding
569     +LineEnding
570     +'begin'+LineEnding
571     +'end.'+LineEnding
572     +LineEnding;
573   AProject.MainFile.SetSourceText(NewSource,true);
574 
575   AProject.LazCompilerOptions.UnitOutputDirectory:='lib'+PathDelim+'$(TargetCPU)-$(TargetOS)';
576   AProject.LazCompilerOptions.TargetFilename:='project1';
577   AProject.LazCompilerOptions.Win32GraphicApp:=false;
578   AProject.LazCompilerOptions.RelocatableUnit:=true;
579 end;
580 
TProjectLibraryDescriptor.CreateStartFilesnull581 function TProjectLibraryDescriptor.CreateStartFiles(AProject: TLazProject): TModalResult;
582 begin
583   Result:=LazarusIDE.DoOpenEditorFile(AProject.MainFile.Filename,-1,-1,
584                                       [ofProjectLoading,ofRegularFile]);
585 end;
586 
587 end.
588 
589