diff --git a/.gitattributes b/.gitattributes index 14428b80bb..4f2091c630 100644 --- a/.gitattributes +++ b/.gitattributes @@ -4008,13 +4008,17 @@ components/pas2js/Makefile svneol=native#text/plain components/pas2js/Makefile.compiled svneol=native#text/plain components/pas2js/Makefile.fpc svneol=native#text/plain components/pas2js/Pas2JSDsgn.compiled svneol=native#text/plain +components/pas2js/defaults.inc svneol=native#text/plain components/pas2js/fpmake.pp svneol=native#text/plain +components/pas2js/frmpas2jsatompackagesettings.lfm svneol=native#text/plain +components/pas2js/frmpas2jsatompackagesettings.pas svneol=native#text/plain components/pas2js/frmpas2jsbrowserprojectoptions.lfm svneol=native#text/plain components/pas2js/frmpas2jsbrowserprojectoptions.pp svneol=native#text/plain components/pas2js/frmpas2jsnodejsprojectoptions.lfm svneol=native#text/plain components/pas2js/frmpas2jsnodejsprojectoptions.pp svneol=native#text/plain components/pas2js/frmpas2jswebservers.lfm svneol=native#text/plain components/pas2js/frmpas2jswebservers.pp svneol=native#text/plain +components/pas2js/languages/regpas2jsatom.pot svneol=native#text/plain components/pas2js/languages/strpas2jsdesign.fr.po svneol=native#text/plain components/pas2js/languages/strpas2jsdesign.hu.po svneol=native#text/plain components/pas2js/languages/strpas2jsdesign.pot svneol=native#text/plain @@ -4032,6 +4036,7 @@ components/pas2js/pjsdsgnoptsframe.pas svneol=native#text/plain components/pas2js/pjsdsgnregister.pas svneol=native#text/plain components/pas2js/pjsprojectoptions.lfm svneol=native#text/plain components/pas2js/pjsprojectoptions.pp svneol=native#text/plain +components/pas2js/regpas2jsatom.pas svneol=native#text/plain components/pas2js/strpas2jsdesign.pp svneol=native#text/plain components/plotfunction/demo/event/frmmain.lfm svneol=native#text/plain components/plotfunction/demo/event/frmmain.pp svneol=native#text/plain diff --git a/components/pas2js/defaults.inc b/components/pas2js/defaults.inc new file mode 100644 index 0000000000..1b125f12f8 --- /dev/null +++ b/components/pas2js/defaults.inc @@ -0,0 +1,178 @@ +procedure getDefaultMenuFile(S : TStrings); +begin + With S do + begin + Add('{'); + Add(' "context-menu": {'); + Add(' "atom-text-editor": ['); + Add(' {'); + Add(' "label": "Toggle %PACKAGENAME%",'); + Add(' "command": "%PACKAGENAME%:toggle"'); + Add(' }'); + Add(' ]'); + Add(' },'); + Add(' "menu": ['); + Add(' {'); + Add(' "label": "Packages",'); + Add(' "submenu": ['); + Add(' {'); + Add(' "label": "%PACKAGENAME%",'); + Add(' "submenu": ['); + Add(' {'); + Add(' "label": "Toggle",'); + Add(' "command": "%PACKAGENAME%:toggle"'); + Add(' }'); + Add(' ]'); + Add(' }'); + Add(' ]'); + Add(' }'); + Add(' ]'); + Add('}'); + end; + +end; + +procedure getDefaultCSSFile(S : TStrings); + +begin + With S do + begin + Add('// The ui-variables file is provided by base themes provided by Atom.'); + Add('//'); + Add('// See https://github.com/atom/atom-dark-ui/blob/master/styles/ui-variables.less'); + Add('// for a full listing of what''s available.'); + Add('@import "ui-variables";'); + Add(''); + Add('.%PACKAGENAME% {'); + Add('}'); + end; +end; + + +Procedure GetDefaultGlueFile(S : TStrings); + +begin + With S do + begin + Add('''use babel'';'); + Add(''); + Add('import { CompositeDisposable } from ''atom'';'); + Add('import { pas, rtl } from ''./%PACKAGEPROJECTNAME%.js'';'); + Add(''); + Add('export default {'); + Add(' activate(state) {'); + Add(' rtl.run();'); + Add(' this.subscriptions = new CompositeDisposable();'); + Add(' this.atomEnv = {'); + Add(' atomGlobal : atom,'); + Add(' subscriptions : this.subscriptions,'); + Add(' initialState : state'); + Add(' }'); + Add(' this.atomHandler = {'); + Add(' onDeactivate : function (a) {},'); + Add(' onSerialize : function (a,o) {}'); + Add(' }'); + Add(' pas.program.InitAtom(this.atomEnv,this.atomHandler);'); + Add(' },'); + Add(''); + Add(' deactivate() {'); + Add(' if (this.atomHandler.onDeactivate) {'); + Add(' this.atomHandler.onDeactivate(this.atomEnv)'); + Add(' }'); + Add(' this.subscriptions.dispose();'); + Add(' },'); + Add(''); + Add(' serialize() {'); + Add(' var obj = {};'); + Add(' if (this.atomHandler.onSerialize) {'); + Add(' this.atomHandler.onSerialize(this.atomEnv,obj)'); + Add(' }'); + Add(' return obj;'); + Add(' }'); + Add('};'); + end; +end; + +Procedure GetDefaultProjectFile(S : TStrings); + +begin + With S do + begin + Add('program %PACKAGEPROJECTNAME%;'); + Add(''); + Add('{$mode objfpc}'); + Add(''); + Add('uses'); + Add(' JS, Classes, SysUtils, libAtom, atomapp, Web;'); + Add(''); + Add(''); + Add('Type'); + Add(' { %CLASSNAME% }'); + Add(''); + Add(' %CLASSNAME% = Class(TAtomApplication)'); + Add(' Private'); + Add(' Protected'); + Add(' procedure DoActivate(aState : TJSObject); override;'); + Add(' procedure DoDeactivate; override;'); + Add(' procedure DoSerialize(aState : TJSObject); override;'); + Add(' Public'); + Add(' // %PACKAGEHANDLERINTFS%'); + Add(' end;'); + Add(''); + Add(''); + Add('// Do not change the name of this procedure, the Javascript glue code depends on it.'); + Add('// If you do want to change it, change the glue code as well.'); + Add('Procedure InitAtom(aAtom : TAtomEnvironment; aCallBacks : TAtomPackageCallBacks);'); + Add(''); + Add('begin'); + Add(' If Application=Nil then'); + Add(' Application:=%CLASSNAME%.Create(Nil);'); + Add(' Application.SaveAtomEnvironment(aAtom,aCallBacks);'); + Add('end;'); + Add(''); + Add('{ %CLASSNAME% }'); + Add(''); + Add('procedure %CLASSNAME%.DoActivate(aState: TJSObject);'); + Add(''); + Add('Var'); + Add(' cmds : TJSObject;'); + Add('begin'); + Add(' inherited DoActivate(aState);'); + Add(' // %PACKAGEHANDLERREGS%'); + Add('end;'); + Add(''); + Add('procedure %CLASSNAME%.DoDeactivate();'); + Add('begin'); + Add('// Deactivation code here'); + Add('end;'); + Add(''); + Add('procedure %CLASSNAME%.DoSerialize(aState: TJSObject);'); + Add('begin'); + Add(' inherited DoSerialize(aState);'); + Add('end;'); + Add(''); + Add('// %PACKAGEHANDLERIMPLS%'); + + Add('// This code is needed to prevent the pas2js compiler from removing the InitAtom call.'); + Add('var'); + Add(' dummy : JSValue;'); + Add(''); + Add('begin'); + Add(' Application:=%CLASSNAME%.Create(Nil);'); + Add(' dummy:=@InitAtom;'); + Add('end.'); + end; +end; + +Procedure getdefaultKeyMapFile(Src : TStrings); + +begin + With Src do + begin + Add('{'); + Add(' "atom-workspace": {'); + Add(' "ctrl-alt-o": "%PACKAGENAME%:toggle"'); + Add(' }'); + Add('}'); + end; +end; diff --git a/components/pas2js/frmpas2jsatompackagesettings.lfm b/components/pas2js/frmpas2jsatompackagesettings.lfm new file mode 100644 index 0000000000..2a40c54d35 --- /dev/null +++ b/components/pas2js/frmpas2jsatompackagesettings.lfm @@ -0,0 +1,279 @@ +object AtomPackageSettingsForm: TAtomPackageSettingsForm + Left = 357 + Height = 546 + Top = 159 + Width = 588 + Caption = 'New Atom Package' + ClientHeight = 546 + ClientWidth = 588 + OnShow = FormShow + LCLVersion = '2.1.0.0' + object edtDescription: TEdit + AnchorSideLeft.Control = dePackage + AnchorSideTop.Control = dePackage + AnchorSideTop.Side = asrBottom + Left = 120 + Height = 27 + Top = 43 + Width = 446 + Anchors = [akTop, akLeft, akRight] + BorderSpacing.Top = 8 + TabOrder = 0 + end + object lblDescription: TLabel + AnchorSideTop.Control = edtDescription + AnchorSideTop.Side = asrCenter + AnchorSideRight.Control = edtDescription + Left = 24 + Height = 16 + Top = 48 + Width = 88 + Alignment = taRightJustify + Anchors = [akTop, akLeft, akRight] + BorderSpacing.Right = 8 + Caption = '&Description' + FocusControl = edtDescription + ParentColor = False + end + object edtName: TEdit + AnchorSideLeft.Control = edtDescription + AnchorSideTop.Control = edtDescription + AnchorSideTop.Side = asrBottom + Left = 120 + Height = 27 + Top = 78 + Width = 184 + BorderSpacing.Top = 8 + OnEditingDone = edtNameEditingDone + OnKeyPress = edtNameKeyPress + TabOrder = 1 + end + object lblName: TLabel + AnchorSideTop.Control = edtName + AnchorSideTop.Side = asrCenter + AnchorSideRight.Control = edtName + Left = 16 + Height = 16 + Top = 83 + Width = 96 + Alignment = taRightJustify + Anchors = [akTop, akLeft, akRight] + BorderSpacing.Right = 8 + Caption = 'Package &Name' + FocusControl = edtName + ParentColor = False + end + object cbLink: TCheckBox + AnchorSideLeft.Control = edtClassName + AnchorSideTop.Control = edtClassName + AnchorSideTop.Side = asrBottom + Left = 120 + Height = 23 + Top = 149 + Width = 173 + BorderSpacing.Top = 8 + Caption = 'Link in Atom package dir' + TabOrder = 2 + end + object vleCommands: TValueListEditor + AnchorSideLeft.Control = cbLink + AnchorSideTop.Control = cbLink + AnchorSideTop.Side = asrBottom + Left = 120 + Height = 112 + Top = 180 + Width = 446 + Anchors = [akTop, akLeft, akRight] + BorderSpacing.Top = 8 + DefaultColWidth = 192 + FixedCols = 0 + RowCount = 2 + TabOrder = 3 + KeyOptions = [keyEdit, keyAdd, keyDelete] + Options = [goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine, goColSizing, goEditing, goAutoAddRows, goAlwaysShowEditor, goThumbTracking] + TitleCaptions.Strings = ( + 'Name' + 'Function' + ) + ColWidths = ( + 192 + 252 + ) + end + object ButtonPanel1: TButtonPanel + Left = 6 + Height = 38 + Top = 502 + Width = 576 + OKButton.Name = 'OKButton' + OKButton.DefaultCaption = True + HelpButton.Name = 'HelpButton' + HelpButton.DefaultCaption = True + CloseButton.Name = 'CloseButton' + CloseButton.DefaultCaption = True + CancelButton.Name = 'CancelButton' + CancelButton.DefaultCaption = True + TabOrder = 4 + ShowButtons = [pbOK, pbCancel] + end + object lblLicense: TLabel + AnchorSideTop.Control = edtLicense + AnchorSideTop.Side = asrCenter + AnchorSideRight.Control = edtLicense + Left = 56 + Height = 16 + Top = 305 + Width = 56 + Alignment = taRightJustify + Anchors = [akTop, akLeft, akRight] + BorderSpacing.Right = 8 + Caption = '&License' + FocusControl = edtLicense + ParentColor = False + end + object edtLicense: TEdit + AnchorSideLeft.Control = vleCommands + AnchorSideTop.Control = vleCommands + AnchorSideTop.Side = asrBottom + Left = 120 + Height = 27 + Top = 300 + Width = 184 + BorderSpacing.Top = 8 + TabOrder = 5 + end + object lblCommands: TLabel + AnchorSideTop.Control = vleCommands + AnchorSideRight.Control = vleCommands + Left = 32 + Height = 16 + Top = 180 + Width = 80 + Alignment = taRightJustify + Anchors = [akTop, akLeft, akRight] + BorderSpacing.Right = 8 + Caption = '&Commands' + FocusControl = vleCommands + ParentColor = False + end + object lblLicense1: TLabel + AnchorSideTop.Control = edtKeywords + AnchorSideTop.Side = asrCenter + AnchorSideRight.Control = edtKeywords + Left = 44 + Height = 16 + Top = 341 + Width = 68 + Alignment = taRightJustify + Anchors = [akTop, akLeft, akRight] + BorderSpacing.Right = 8 + Caption = '&Keywords' + FocusControl = edtKeywords + ParentColor = False + end + object edtKeywords: TEdit + AnchorSideLeft.Control = edtLicense + AnchorSideTop.Control = edtLicense + AnchorSideTop.Side = asrBottom + Left = 120 + Height = 27 + Top = 336 + Width = 445 + Anchors = [akTop, akLeft, akRight] + BorderSpacing.Top = 9 + TabOrder = 6 + end + object lblCommands1: TLabel + AnchorSideTop.Control = vleActivationCommands + AnchorSideRight.Control = vleActivationCommands + Left = 23 + Height = 32 + Top = 371 + Width = 89 + Alignment = taRightJustify + Anchors = [akTop, akLeft, akRight] + BorderSpacing.Right = 8 + Caption = '&Activation '#10'Commands' + FocusControl = vleActivationCommands + ParentColor = False + end + object vleActivationCommands: TValueListEditor + AnchorSideLeft.Control = edtKeywords + AnchorSideTop.Control = edtKeywords + AnchorSideTop.Side = asrBottom + Left = 120 + Height = 112 + Top = 371 + Width = 445 + Anchors = [akTop, akLeft, akRight] + BorderSpacing.Top = 8 + DefaultColWidth = 192 + FixedCols = 0 + RowCount = 2 + TabOrder = 7 + KeyOptions = [keyEdit, keyAdd, keyDelete, keyUnique] + Options = [goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine, goColSizing, goEditing, goAutoAddRows, goAlwaysShowEditor, goThumbTracking] + TitleCaptions.Strings = ( + 'Command Name' + 'Scope' + ) + ColWidths = ( + 192 + 251 + ) + end + object dePackage: TDirectoryEdit + Left = 120 + Height = 27 + Top = 8 + Width = 447 + ShowHidden = False + ButtonWidth = 23 + NumGlyphs = 1 + Anchors = [akTop, akLeft, akRight] + MaxLength = 0 + TabOrder = 8 + end + object lblDescription1: TLabel + AnchorSideTop.Control = dePackage + AnchorSideTop.Side = asrCenter + AnchorSideRight.Control = dePackage + Left = 34 + Height = 16 + Top = 13 + Width = 78 + Alignment = taRightJustify + Anchors = [akTop, akLeft, akRight] + BorderSpacing.Right = 8 + Caption = '&Directory' + FocusControl = edtDescription + ParentColor = False + end + object lblClassName: TLabel + AnchorSideTop.Control = edtClassName + AnchorSideTop.Side = asrCenter + AnchorSideRight.Control = edtClassName + Left = 32 + Height = 16 + Top = 119 + Width = 79 + Alignment = taRightJustify + Anchors = [akTop, akLeft, akRight] + BorderSpacing.Right = 9 + Caption = '&Class Name' + FocusControl = edtClassName + ParentColor = False + end + object edtClassName: TEdit + AnchorSideLeft.Control = edtName + AnchorSideTop.Control = edtName + AnchorSideTop.Side = asrBottom + Left = 120 + Height = 27 + Top = 114 + Width = 184 + BorderSpacing.Top = 9 + OnKeyPress = edtClassNameKeyPress + TabOrder = 9 + end +end diff --git a/components/pas2js/frmpas2jsatompackagesettings.pas b/components/pas2js/frmpas2jsatompackagesettings.pas new file mode 100644 index 0000000000..30c97ed57a --- /dev/null +++ b/components/pas2js/frmpas2jsatompackagesettings.pas @@ -0,0 +1,167 @@ +unit frmPas2jsAtomPackageSettings; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, ValEdit, + ButtonPanel, EditBtn; + +type + + { TAtomPackageSettingsForm } + + TAtomPackageSettingsForm = class(TForm) + ButtonPanel1: TButtonPanel; + cbLink: TCheckBox; + dePackage: TDirectoryEdit; + edtDescription: TEdit; + edtKeywords: TEdit; + edtName: TEdit; + edtLicense: TEdit; + edtClassName: TEdit; + lblCommands1: TLabel; + lblDescription: TLabel; + lblDescription1: TLabel; + lblLicense1: TLabel; + lblName: TLabel; + lblLicense: TLabel; + lblCommands: TLabel; + lblClassName: TLabel; + vleCommands: TValueListEditor; + vleActivationCommands: TValueListEditor; + procedure edtClassNameKeyPress(Sender: TObject; var Key: char); + procedure edtNameEditingDone(Sender: TObject); + procedure edtNameKeyPress(Sender: TObject; var Key: char); + procedure FormShow(Sender: TObject); + private + Function GetValueCtl(aIndex : Integer) : TWinControl; + function GetB(AIndex: Integer): Boolean; + function GetS(AIndex: Integer): String; + function GetSL(AIndex: Integer): TStrings; + procedure SetB(AIndex: Integer; AValue: Boolean); + procedure SetS(AIndex: Integer; AValue: String); + procedure SetSL(AIndex: Integer; AValue: TStrings); + + public + Property PkgDescription: String Index 0 read GetS Write SetS; + Property PkgName : String Index 1 read GetS Write Sets; + Property PkgKeyWords : String Index 2 read GetS Write SetS; + Property PkgLink : Boolean Index 3 read GetB Write SetB; + Property PkgCommands : TStrings Index 4 Read GetSL Write SetSL; + Property PkgActivationCommands : TStrings Index 5 Read GetSL Write SetSL; + Property PkgLicense : String Index 6 read GetS Write SetS; + Property PkgDir : String Index 7 read GetS Write SetS; + Property PkgClassName : String Index 8 read GetS Write SetS; + end; + + function StripNonIdentifierChars(S : String) : string; + +var + AtomPackageSettingsForm: TAtomPackageSettingsForm; + +implementation + +{$R *.lfm} + +{ TAtomPackageSettingsForm } + +procedure TAtomPackageSettingsForm.edtNameKeyPress(Sender: TObject; + var Key: char); +begin + if Not (Upcase(key) in ['A'..'Z','-',#8,#127]) then + Key:=#0; +end; + +procedure TAtomPackageSettingsForm.FormShow(Sender: TObject); +begin +{$IFDEF WINDOWS} + cbLink.checked:=False; + cbLink.Enabled:=False; +{$ENDIF} +end; + +procedure TAtomPackageSettingsForm.edtClassNameKeyPress(Sender: TObject; + var Key: char); +begin + if Not (Upcase(Key) in ['A'..'Z','_',#8,#127]) then + Key:=#0; +end; + +function StripNonIdentifierChars(S : String) : string; + +begin + // Name will only contain characters and - + Result:=StringReplace(S,'-','_',[rfReplaceAll]); +end; + +procedure TAtomPackageSettingsForm.edtNameEditingDone(Sender: TObject); + +begin + if (edtClassName.Text='') then + edtClassName.Text:='T'+StripNonIdentifierChars(edtName.Text)+'Application'; +end; + +function TAtomPackageSettingsForm.GetValueCtl(aIndex: Integer): TWinControl; +begin + Case AIndex of + 0 : Result:=edtDescription; + 1 : Result:=edtName; + 2 : Result:=edtKeywords; + 3 : Result:=cbLink; + 4 : Result:=vleCommands; + 5 : Result:=vleActivationCommands; + 6 : Result:=edtLicense; + 7 : Result:=dePackage; + 8 : Result:=edtClassName; + end; +end; + +function TAtomPackageSettingsForm.GetB(AIndex: Integer): Boolean; +begin + Result:=(GetValueCtl(aIndex) as TCheckbox).Checked; +end; + +function TAtomPackageSettingsForm.GetS(AIndex: Integer): String; + +Var + Ctl : TWinControl; + +begin + ctl:=GetValueCtl(aIndex); + if Ctl is TCustomEdit then + Result:=(Ctl as TCustomEdit).text + else + Result:=(Ctl as TCustomEditButton).Text; +end; + +function TAtomPackageSettingsForm.GetSL(AIndex: Integer): TStrings; +begin + Result:=(GetValueCtl(aIndex) as TValueListEditor).Strings; +end; + +procedure TAtomPackageSettingsForm.SetB(AIndex: Integer; AValue: Boolean); +begin + (GetValueCtl(aIndex) as TCheckbox).Checked:=aValue; +end; + +procedure TAtomPackageSettingsForm.SetS(AIndex: Integer; AValue: String); +Var + Ctl : TWinControl; + +begin + ctl:=GetValueCtl(aIndex); + if Ctl is TCustomEdit then + (Ctl as TCustomEdit).text:=aValue + else + (Ctl as TCustomEditButton).Text:=aValue; +end; + +procedure TAtomPackageSettingsForm.SetSL(AIndex: Integer; AValue: TStrings); +begin + (GetValueCtl(aIndex) as TValueListEditor).Strings.Assign(aValue); +end; + +end. + diff --git a/components/pas2js/languages/regpas2jsatom.pot b/components/pas2js/languages/regpas2jsatom.pot new file mode 100644 index 0000000000..82df4f04c9 --- /dev/null +++ b/components/pas2js/languages/regpas2jsatom.pot @@ -0,0 +1,11 @@ +msgid "" +msgstr "Content-Type: text/plain; charset=UTF-8" + +#: regpas2jsatom.snewatompackage +msgid "Pas2js Atom package" +msgstr "" + +#: regpas2jsatom.snewatompackagedescr +msgid "Create a new pas2js Atom package" +msgstr "" + diff --git a/components/pas2js/languages/strpas2jsdesign.fr.po b/components/pas2js/languages/strpas2jsdesign.fr.po index 9f0adfc835..51de7bea14 100644 --- a/components/pas2js/languages/strpas2jsdesign.fr.po +++ b/components/pas2js/languages/strpas2jsdesign.fr.po @@ -143,6 +143,10 @@ msgstr "Réinitialiser la commande d'exécution" msgid "Run RTL when all page resources are fully loaded" msgstr "Exécuter la RTL quand toutes les pages de ressources sont totalement chargées" +#: strpas2jsdesign.pjsdselectatomtemplatedir +msgid "Select atom package template directory" +msgstr "" + #: strpas2jsdesign.pjsdselectbrowserexecutable msgid "Select browser executable" msgstr "Sélectionner l'exécutable du navigateur" diff --git a/components/pas2js/languages/strpas2jsdesign.hu.po b/components/pas2js/languages/strpas2jsdesign.hu.po index 1d397e786c..a444bc4f2b 100644 --- a/components/pas2js/languages/strpas2jsdesign.hu.po +++ b/components/pas2js/languages/strpas2jsdesign.hu.po @@ -143,6 +143,10 @@ msgstr "A futtatás parancs alaphelyzetbe állítása" msgid "Run RTL when all page resources are fully loaded" msgstr "Az RTL csak a lap minden erőforrásának betöltése után induljon" +#: strpas2jsdesign.pjsdselectatomtemplatedir +msgid "Select atom package template directory" +msgstr "" + #: strpas2jsdesign.pjsdselectbrowserexecutable msgid "Select browser executable" msgstr "A böngésző alkalmazás kiválasztása" diff --git a/components/pas2js/languages/strpas2jsdesign.pot b/components/pas2js/languages/strpas2jsdesign.pot index 0ab8086473..84ecf3edd5 100644 --- a/components/pas2js/languages/strpas2jsdesign.pot +++ b/components/pas2js/languages/strpas2jsdesign.pot @@ -133,6 +133,10 @@ msgstr "" msgid "Run RTL when all page resources are fully loaded" msgstr "" +#: strpas2jsdesign.pjsdselectatomtemplatedir +msgid "Select atom package template directory" +msgstr "" + #: strpas2jsdesign.pjsdselectbrowserexecutable msgid "Select browser executable" msgstr "" diff --git a/components/pas2js/languages/strpas2jsdesign.pt_BR.po b/components/pas2js/languages/strpas2jsdesign.pt_BR.po index b710d7a42c..d2579b2c81 100644 --- a/components/pas2js/languages/strpas2jsdesign.pt_BR.po +++ b/components/pas2js/languages/strpas2jsdesign.pt_BR.po @@ -145,6 +145,10 @@ msgstr "Comando redefinir execução" msgid "Run RTL when all page resources are fully loaded" msgstr "Rodar RTL quando todas as páginas de recursos forem totalmente carregadas" +#: strpas2jsdesign.pjsdselectatomtemplatedir +msgid "Select atom package template directory" +msgstr "" + #: strpas2jsdesign.pjsdselectbrowserexecutable msgid "Select browser executable" msgstr "Selecionar executável do navegador" diff --git a/components/pas2js/languages/strpas2jsdesign.ru.po b/components/pas2js/languages/strpas2jsdesign.ru.po index 9236077548..02eb1e27d2 100644 --- a/components/pas2js/languages/strpas2jsdesign.ru.po +++ b/components/pas2js/languages/strpas2jsdesign.ru.po @@ -143,6 +143,10 @@ msgstr "Сбросить команду запуска" msgid "Run RTL when all page resources are fully loaded" msgstr "Запускать RTL после полной загрузки всех ресурсов страницы" +#: strpas2jsdesign.pjsdselectatomtemplatedir +msgid "Select atom package template directory" +msgstr "" + #: strpas2jsdesign.pjsdselectbrowserexecutable msgid "Select browser executable" msgstr "Выберите исполнимый файл браузера" diff --git a/components/pas2js/languages/strpas2jsdesign.tr.po b/components/pas2js/languages/strpas2jsdesign.tr.po index e7a9f4d99c..3ca72790f5 100644 --- a/components/pas2js/languages/strpas2jsdesign.tr.po +++ b/components/pas2js/languages/strpas2jsdesign.tr.po @@ -143,6 +143,10 @@ msgstr "" msgid "Run RTL when all page resources are fully loaded" msgstr "" +#: strpas2jsdesign.pjsdselectatomtemplatedir +msgid "Select atom package template directory" +msgstr "" + #: strpas2jsdesign.pjsdselectbrowserexecutable msgid "Select browser executable" msgstr "" diff --git a/components/pas2js/languages/strpas2jsdesign.uk.po b/components/pas2js/languages/strpas2jsdesign.uk.po index 6f1e396dc5..bd180541dd 100644 --- a/components/pas2js/languages/strpas2jsdesign.uk.po +++ b/components/pas2js/languages/strpas2jsdesign.uk.po @@ -145,6 +145,10 @@ msgstr "Скинути команду запуску" msgid "Run RTL when all page resources are fully loaded" msgstr "Після повного завантаження всіх ресурсів сторінки запустити RTL" +#: strpas2jsdesign.pjsdselectatomtemplatedir +msgid "Select atom package template directory" +msgstr "" + #: strpas2jsdesign.pjsdselectbrowserexecutable msgid "Select browser executable" msgstr "Вибрати виконуваний файл оглядача" diff --git a/components/pas2js/languages/strpas2jsdesign.zh_CN.po b/components/pas2js/languages/strpas2jsdesign.zh_CN.po index 8273d67c76..9a0c1cdef4 100644 --- a/components/pas2js/languages/strpas2jsdesign.zh_CN.po +++ b/components/pas2js/languages/strpas2jsdesign.zh_CN.po @@ -144,6 +144,10 @@ msgstr "" msgid "Run RTL when all page resources are fully loaded" msgstr "" +#: strpas2jsdesign.pjsdselectatomtemplatedir +msgid "Select atom package template directory" +msgstr "" + #: strpas2jsdesign.pjsdselectbrowserexecutable msgid "Select browser executable" msgstr "" diff --git a/components/pas2js/pas2jsdsgn.lpk b/components/pas2js/pas2jsdsgn.lpk index cf4635362c..a5c79ada39 100644 --- a/components/pas2js/pas2jsdsgn.lpk +++ b/components/pas2js/pas2jsdsgn.lpk @@ -1,6 +1,6 @@ - + @@ -18,7 +18,7 @@ - + @@ -56,7 +56,25 @@ + + + + + + + + + + + + + + + + + + diff --git a/components/pas2js/pas2jsdsgn.pas b/components/pas2js/pas2jsdsgn.pas index 703a33d199..303af81043 100644 --- a/components/pas2js/pas2jsdsgn.pas +++ b/components/pas2js/pas2jsdsgn.pas @@ -10,13 +10,15 @@ interface uses PJSDsgnRegister, PJSDsgnOptsFrame, frmpas2jsbrowserprojectoptions, PJSDsgnOptions, frmpas2jsnodejsprojectoptions, pjscontroller, - frmpas2jswebservers, strpas2jsdesign, pjsprojectoptions, LazarusPackageIntf; + frmpas2jswebservers, strpas2jsdesign, pjsprojectoptions, + frmPas2jsAtomPackageSettings, regpas2jsatom, LazarusPackageIntf; implementation procedure Register; begin RegisterUnit('PJSDsgnRegister', @PJSDsgnRegister.Register); + RegisterUnit('regpas2jsatom', @regpas2jsatom.Register); end; initialization diff --git a/components/pas2js/pjsdsgnoptions.pas b/components/pas2js/pjsdsgnoptions.pas index 33e77dd41f..a63d046f3f 100644 --- a/components/pas2js/pjsdsgnoptions.pas +++ b/components/pas2js/pjsdsgnoptions.pas @@ -34,7 +34,8 @@ Type p2jcoBrowserFilename, p2jcoHTTPServerFilename, p2jcoHTTPServerPort, - p2jcoNodeJSFilename + p2jcoNodeJSFilename, + p2jcoAtomTemplateDir ); TPas2jsCachedOptions = set of TPas2jsCachedOption; const @@ -42,7 +43,8 @@ const p2jcoCompilerFilename, p2jcoBrowserFilename, p2jcoHTTPServerFilename, - p2jcoNodeJSFilename + p2jcoNodeJSFilename, + p2jcoAtomTemplateDir ]; type @@ -63,6 +65,7 @@ type FSavedStamp: int64; FStartAtPort: Word; procedure DoOptsChanged(Sender: TObject); + function GetAtomTemplateDir: String; function GetBrowserFileName: String; function GetCompilerFilename: string; function GetStartAtPort: Word; @@ -70,6 +73,7 @@ type function GetModified: boolean; function GetNodeJSFileName: string; function GetParsedOptionValue(Option: TPas2jsCachedOption): string; + procedure SetAtomTemplateDir(AValue: String); procedure SetBrowserFileName(AValue: String); procedure SetWebServerFileName(AValue: string); procedure SetHTTPServerOpts(AValue: TStrings); @@ -100,6 +104,7 @@ type Property StartAtPort : Word Read GetStartAtPort Write SetStartAtPort; property ChangeStamp: int64 read FChangeStamp; property Modified: boolean read GetModified write SetModified; + Property AtomTemplateDir : String Read GetAtomTemplateDir Write SetAtomTemplateDir; end; var @@ -217,6 +222,11 @@ begin Self.Modified:=True; end; +function TPas2jsOptions.GetAtomTemplateDir: String; +begin + Result:=FCachedOptions[p2jcoBrowserFilename].RawValue; +end; + function TPas2jsOptions.GetCompilerFilename: string; begin Result:=FCachedOptions[p2jcoCompilerFilename].RawValue; @@ -398,6 +408,12 @@ begin Result:=p^.ParsedValue; end; +procedure TPas2jsOptions.SetAtomTemplateDir(AValue: String); +begin + AValue:=TrimFilename(AValue); + SetCachedOption(p2jcoAtomTemplateDir,AValue); +end; + function TPas2jsOptions.GetParsedBrowserFilename: string; begin Result:=GetParsedOptionValue(p2jcoBrowserFilename); diff --git a/components/pas2js/pjsdsgnoptsframe.lfm b/components/pas2js/pjsdsgnoptsframe.lfm index 280a87f80b..d8cf6ca35c 100644 --- a/components/pas2js/pjsdsgnoptsframe.lfm +++ b/components/pas2js/pjsdsgnoptsframe.lfm @@ -1,11 +1,11 @@ object Pas2jsOptionsFrame: TPas2jsOptionsFrame Left = 0 - Height = 430 + Height = 428 Top = 0 - Width = 493 + Width = 507 BorderSpacing.Left = 6 - ClientHeight = 430 - ClientWidth = 493 + ClientHeight = 428 + ClientWidth = 507 ParentShowHint = False ShowHint = True TabOrder = 0 @@ -15,9 +15,9 @@ object Pas2jsOptionsFrame: TPas2jsOptionsFrame AnchorSideLeft.Control = Owner AnchorSideTop.Control = Owner Left = 6 - Height = 15 + Height = 16 Top = 6 - Width = 151 + Width = 174 BorderSpacing.Left = 6 BorderSpacing.Top = 6 Caption = 'Pas2JS command executable' @@ -31,12 +31,12 @@ object Pas2jsOptionsFrame: TPas2jsOptionsFrame AnchorSideTop.Side = asrBottom AnchorSideRight.Control = Pas2jsPathBrowseButton Left = 6 - Height = 23 - Top = 23 - Width = 446 + Height = 27 + Top = 24 + Width = 472 Anchors = [akTop, akLeft, akRight] BorderSpacing.Top = 2 - ItemHeight = 15 + ItemHeight = 0 TabOrder = 0 end object Pas2jsPathBrowseButton: TButton @@ -45,10 +45,10 @@ object Pas2jsOptionsFrame: TPas2jsOptionsFrame AnchorSideRight.Side = asrBottom AnchorSideBottom.Control = Pas2jsPathComboBox AnchorSideBottom.Side = asrBottom - Left = 452 - Height = 23 - Top = 23 - Width = 35 + Left = 478 + Height = 27 + Top = 24 + Width = 23 Anchors = [akTop, akRight, akBottom] AutoSize = True BorderSpacing.Right = 6 @@ -63,9 +63,9 @@ object Pas2jsOptionsFrame: TPas2jsOptionsFrame AnchorSideTop.Control = Pas2jsPathComboBox AnchorSideTop.Side = asrBottom Left = 6 - Height = 15 - Top = 54 - Width = 162 + Height = 16 + Top = 59 + Width = 179 BorderSpacing.Left = 6 BorderSpacing.Top = 8 Caption = 'Simple HTTP Server command' @@ -78,10 +78,10 @@ object Pas2jsOptionsFrame: TPas2jsOptionsFrame AnchorSideRight.Side = asrBottom AnchorSideBottom.Control = HTTPServerComboBox AnchorSideBottom.Side = asrBottom - Left = 452 - Height = 25 - Top = 69 - Width = 35 + Left = 478 + Height = 29 + Top = 75 + Width = 23 Anchors = [akTop, akRight, akBottom] AutoSize = True BorderSpacing.Right = 6 @@ -95,12 +95,12 @@ object Pas2jsOptionsFrame: TPas2jsOptionsFrame AnchorSideTop.Side = asrBottom AnchorSideRight.Control = HTTPServerBrowseButton Left = 6 - Height = 23 - Top = 71 - Width = 446 + Height = 27 + Top = 77 + Width = 472 Anchors = [akTop, akLeft, akRight] BorderSpacing.Top = 2 - ItemHeight = 15 + ItemHeight = 0 TabOrder = 3 end object ServerPortSpinEdit: TSpinEdit @@ -108,8 +108,8 @@ object Pas2jsOptionsFrame: TPas2jsOptionsFrame AnchorSideTop.Control = ServerPortLabel AnchorSideTop.Side = asrBottom Left = 6 - Height = 23 - Top = 119 + Height = 27 + Top = 130 Width = 74 BorderSpacing.Top = 2 MaxValue = 65353 @@ -122,9 +122,9 @@ object Pas2jsOptionsFrame: TPas2jsOptionsFrame AnchorSideTop.Control = HTTPServerComboBox AnchorSideTop.Side = asrBottom Left = 6 - Height = 15 - Top = 102 - Width = 106 + Height = 16 + Top = 112 + Width = 124 BorderSpacing.Left = 6 BorderSpacing.Top = 8 Caption = 'Standard server port' @@ -136,12 +136,12 @@ object Pas2jsOptionsFrame: TPas2jsOptionsFrame AnchorSideTop.Side = asrBottom AnchorSideRight.Control = BBrowserBrowseButton Left = 6 - Height = 23 - Top = 261 - Width = 446 + Height = 27 + Top = 278 + Width = 472 Anchors = [akTop, akLeft, akRight] BorderSpacing.Top = 2 - ItemHeight = 15 + ItemHeight = 0 TabOrder = 5 Text = 'BrowserComboBox' end @@ -150,9 +150,9 @@ object Pas2jsOptionsFrame: TPas2jsOptionsFrame AnchorSideTop.Control = HTTPServerOptionsMemo AnchorSideTop.Side = asrBottom Left = 6 - Height = 15 - Top = 244 - Width = 250 + Height = 16 + Top = 260 + Width = 283 BorderSpacing.Left = 6 BorderSpacing.Top = 6 Caption = 'Browser to launch when opening project HTML' @@ -164,10 +164,10 @@ object Pas2jsOptionsFrame: TPas2jsOptionsFrame AnchorSideRight.Side = asrBottom AnchorSideBottom.Control = BrowserComboBox AnchorSideBottom.Side = asrBottom - Left = 452 - Height = 23 - Top = 261 - Width = 35 + Left = 478 + Height = 27 + Top = 278 + Width = 23 Anchors = [akTop, akRight, akBottom] AutoSize = True BorderSpacing.Right = 6 @@ -180,9 +180,9 @@ object Pas2jsOptionsFrame: TPas2jsOptionsFrame AnchorSideTop.Control = BrowserComboBox AnchorSideTop.Side = asrBottom Left = 6 - Height = 15 - Top = 290 - Width = 99 + Height = 16 + Top = 311 + Width = 114 BorderSpacing.Left = 6 BorderSpacing.Top = 6 Caption = 'Node.js executable' @@ -194,12 +194,12 @@ object Pas2jsOptionsFrame: TPas2jsOptionsFrame AnchorSideTop.Side = asrBottom AnchorSideRight.Control = NodeJSBrowseButton Left = 6 - Height = 23 - Top = 307 - Width = 446 + Height = 27 + Top = 329 + Width = 472 Anchors = [akTop, akLeft, akRight] BorderSpacing.Top = 2 - ItemHeight = 15 + ItemHeight = 0 TabOrder = 7 Text = 'NodeJSComboBox' end @@ -209,10 +209,10 @@ object Pas2jsOptionsFrame: TPas2jsOptionsFrame AnchorSideRight.Side = asrBottom AnchorSideBottom.Control = NodeJSComboBox AnchorSideBottom.Side = asrBottom - Left = 452 - Height = 23 - Top = 307 - Width = 35 + Left = 478 + Height = 27 + Top = 329 + Width = 23 Anchors = [akTop, akRight, akBottom] AutoSize = True BorderSpacing.Right = 6 @@ -228,8 +228,8 @@ object Pas2jsOptionsFrame: TPas2jsOptionsFrame AnchorSideRight.Side = asrBottom Left = 6 Height = 73 - Top = 165 - Width = 481 + Top = 181 + Width = 495 Anchors = [akTop, akLeft, akRight] BorderSpacing.Left = 6 BorderSpacing.Top = 2 @@ -241,12 +241,57 @@ object Pas2jsOptionsFrame: TPas2jsOptionsFrame AnchorSideTop.Control = ServerPortSpinEdit AnchorSideTop.Side = asrBottom Left = 6 - Height = 15 - Top = 148 - Width = 291 + Height = 16 + Top = 163 + Width = 327 BorderSpacing.Left = 6 BorderSpacing.Top = 6 Caption = 'HTTP Server extra command-line options (one per line)' ParentColor = False end + object lblAtomTemplateDir: TLabel + AnchorSideLeft.Control = Owner + AnchorSideTop.Control = NodeJSComboBox + AnchorSideTop.Side = asrBottom + Left = 6 + Height = 16 + Top = 362 + Width = 200 + BorderSpacing.Left = 6 + BorderSpacing.Top = 6 + Caption = 'Atom package template directory' + ParentColor = False + end + object AtomTemplateDirComboBox: TComboBox + AnchorSideLeft.Control = lblAtomTemplateDir + AnchorSideTop.Control = lblAtomTemplateDir + AnchorSideTop.Side = asrBottom + AnchorSideRight.Control = NodeJSBrowseButton + Left = 6 + Height = 27 + Top = 380 + Width = 472 + Anchors = [akTop, akLeft, akRight] + BorderSpacing.Top = 2 + ItemHeight = 0 + TabOrder = 10 + Text = 'AtomTemplateDirComboBox' + end + object NodeJSBrowseButton1: TButton + AnchorSideTop.Control = AtomTemplateDirComboBox + AnchorSideRight.Control = Owner + AnchorSideRight.Side = asrBottom + AnchorSideBottom.Control = AtomTemplateDirComboBox + AnchorSideBottom.Side = asrBottom + Left = 478 + Height = 27 + Top = 380 + Width = 23 + Anchors = [akTop, akRight, akBottom] + AutoSize = True + BorderSpacing.Right = 6 + Caption = '...' + OnClick = NodeJSBrowseButton1Click + TabOrder = 11 + end end diff --git a/components/pas2js/pjsdsgnoptsframe.pas b/components/pas2js/pjsdsgnoptsframe.pas index 3e8447ad64..8272c198d4 100644 --- a/components/pas2js/pjsdsgnoptsframe.pas +++ b/components/pas2js/pjsdsgnoptsframe.pas @@ -31,8 +31,11 @@ Type HTTPServerCmdLabel: TLabel; HTTPServerComboBox: TComboBox; NodeJSBrowseButton: TButton; + NodeJSBrowseButton1: TButton; NodeJSComboBox: TComboBox; + AtomTemplateDirComboBox: TComboBox; NodeJSLabel: TLabel; + lblAtomTemplateDir: TLabel; Pas2jsPathBrowseButton: TButton; Pas2jsPathComboBox: TComboBox; Pas2jsPathLabel: TLabel; @@ -42,6 +45,7 @@ Type HTTPServerOptionsMemo: TMemo; procedure BBrowserBrowseButtonClick(Sender: TObject); procedure HTTPServerBrowseButtonClick(Sender: TObject); + procedure NodeJSBrowseButton1Click(Sender: TObject); procedure NodeJSBrowseButtonClick(Sender: TObject); procedure Pas2jsPathBrowseButtonClick(Sender: TObject); private @@ -102,6 +106,21 @@ begin end; end; +procedure TPas2jsOptionsFrame.NodeJSBrowseButton1Click(Sender: TObject); + +var + ADirname: String; + +begin + aDirName:=AtomTemplateDirComboBox.Text; + if SelectDirectory(pjsdSelectAtomTemplateDir,aDirName,aDirName) then + begin + ADirName:=CleanAndExpandFilename(ADirName); + SetComboBoxText(AtomTemplateDirComboBox,ADirName,cstFilename,30); + PJSOptions.AtomTemplateDir:=ADirName; + end; +end; + procedure TPas2jsOptionsFrame.NodeJSBrowseButtonClick(Sender: TObject); var OpenDialog: TOpenDialog; diff --git a/components/pas2js/regpas2jsatom.pas b/components/pas2js/regpas2jsatom.pas new file mode 100644 index 0000000000..4cd358ec05 --- /dev/null +++ b/components/pas2js/regpas2jsatom.pas @@ -0,0 +1,507 @@ +unit regpas2jsatom; + +{$mode objfpc}{$H+} +interface + +uses + Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, + ProjectIntf, BaseIDEIntf, LazIDEIntf, LazFileUtils; + +type + + { TAtomPackageProjectDescriptor } + + TAtomPackageProjectDescriptor = class(TProjectDescriptor) + Private + FPackageClassName, + FPackageDir, + FPackageLicense, + FPackageName, + FPackageDescription : String; + FlinkPackage : Boolean; + FKeyWords, + FCommands : TStrings; + FActivationCommands : TStrings; + procedure AddCSSFile(aProject: TLazProject); + procedure AddFileToProject(aProject: TLazProject; const aFileName: string); + procedure AddGlueFile(aProject: TLazProject); + procedure AddKeyMapFile(aProject: TLazProject); + procedure AddMenuFile(aProject: TLazProject); + procedure AddPackageJSONFile(aProject: TLazProject); + procedure AddProjectFile(AProject: TLazProject); + procedure CreateProjectDirs; + procedure CreateProjectSource(Src: TStrings); + procedure DoDefaultReplacements(Src: TStrings); + procedure InsertHandlerDefinitions(Src: TStrings; aIndex, aIndent: Integer); + procedure InsertHandlerImplementations(Src: TStrings; aIndex: Integer); + procedure InsertHandlerRegistrations(Src: TStrings; aIndex: Integer); + function LoadDefault(Src: TStrings; aFileName: string): boolean; + Function ShowOptionsDialog : TModalResult; + public + constructor Create(); override; + 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; + published + { Published declarations } + end; + +procedure Register; + +implementation + +uses + {$IFDEF UNIX} + baseunix, + {$ENDIF} + + fpjson,frmpas2jsatompackagesettings, CompOptsIntf, + NewItemIntf, MenuIntf, pjsprojectoptions, pjsdsgnoptions; + +Resourcestring + SNewAtomPackage = 'Pas2js Atom package'; + SNewAtomPackageDescr = 'Create a new pas2js Atom package'; + +Var + AtomProjDesc:TAtomPackageProjectDescriptor; + + +procedure Register; + +begin + //RegisterIdeMenuCommand(itmOptionsDialogs,STemplateSettings,SProjectTemplateSettings,nil,@ChangeSettings); + AtomProjDesc:=TAtomPackageProjectDescriptor.Create(); + RegisterProjectDescriptor(AtomProjDesc); +end; + + +{ TAtomPackageProjectDescriptor } + +function TAtomPackageProjectDescriptor.ShowOptionsDialog : TModalResult; + +begin + With TAtomPackageSettingsForm.Create(Application) do + try + PkgDescription:=FPackageDescription; + PkgName:=FPackageName; + pkgClassName:= FPackageClassName; + pkgLink:=FlinkPackage; + PkgCommands:=FCommands; + PkgActivationCommands:=FActivationCommands; + PkgLicense:=FPackageLicense; + PkgKeyWords:=FkeyWords.CommaText; + PkgDir:=FPackageDir; + Result:=ShowModal; + if (Result=mrOK) then + begin + FPackageDescription:=PkgDescription; + FPackageName:=PkgName; + FlinkPackage:=pkgLink; + FCommands.Assign(PkgCommands); + FActivationCommands.Assign(PkgActivationCommands); + FPackageLicense:=PkgLicense; + FKeyWords.CommaText:=PkgKeyWords; + FPackageDir:=IncludeTrailingPathDelimiter(PkgDir); + FPackageClassName:=pkgClassName; + end; + finally + Free; + end; +end; + + +constructor TAtomPackageProjectDescriptor.Create; +begin + inherited Create; + FPackageName:='my-atom-package'; + FPackageDescription:='My atom package'; + FPackageClassName:='TMyAtomPackageApplication'; + FKeyWords:=TStringList.Create; + FPackageLicense:='MIT'; + FLinkPackage:=True; + FCommands:=TStringList.Create; + FActivationCommands:=TStringList.Create; + Name:='pas2jsatompackage'; +end; + +destructor TAtomPackageProjectDescriptor.destroy; +begin + FreeAndNil(FCommands); + FreeAndNil(FKeywords); + FreeAndNil(FActivationCommands); + Inherited; +end; + + +function TAtomPackageProjectDescriptor.GetLocalizedName: string; +begin + Result:=SNewAtomPackage; +end; + +function TAtomPackageProjectDescriptor.GetLocalizedDescription: string; +begin + Result:=SNewAtomPackageDescr; +end; + + +function TAtomPackageProjectDescriptor.DoInitDescriptor: TModalResult; + +begin + FPackageDir:=GetUserDir+'github'+pathdelim+'myatompackage'; + FPackageName:='my-atom-package'; + FPackageDescription:='My atom package'; + FPackageClassName:='TMyAtomPackageApplication'; + FKeyWords:=TStringList.Create; + FPackageLicense:='MIT'; +{$IFDEF UNIX} + FLinkPackage:=True; +{$ELSE} + FLinkPackage:=False; +{$ENDIF} + FCommands.Clear; + FActivationCommands.Clear; + Result:=ShowOptionsDialog; +end; + +Procedure TAtomPackageProjectDescriptor.CreateProjectDirs; + +Const + DirCount = 5; + DefDirs : Array [1..DirCount] of string = + ('','lib','keymaps','menus','styles'); + +Var + S : String; + L : String; + +begin + FPackageDir:=IncludeLeadingPathDelimiter(FPackageDir); + For S in DefDirs do + If not ForceDirectories(FPackageDir+S) then + ShowMessage('Failed to create directory '+FPackageDir+S); +{$IFDEF UNIX} + if FLinkPackage then + begin + L:=Sysutils.GetUserDir+'.atom'+PathDelim+'packages/'+FPackageName; + fpSymlink(PChar(FPackageDir),PChar(L)); + end; +{$ENDIF} +end; + +{$I defaults.inc} + + +Procedure TAtomPackageProjectDescriptor.InsertHandlerDefinitions(Src : TStrings; aIndex,aIndent : Integer); + +Var + I,Cnt : Integer; + Prefix,N,V : String; + + procedure AddLn(aLine : String); + + begin + Src.Insert(aIndex+Cnt,aLine); + inc(cnt); + end; + + +begin + cnt:=0; + Src.Delete(aIndex); + Prefix:=StringOfChar(' ',aIndent-2); // approximate + For I:=0 to FCommands.Count-1 do + begin + FCommands.GetNameValue(I,N,V); + AddLn(Prefix+'Procedure '+V+';'); + end; +end; + +Procedure TAtomPackageProjectDescriptor.InsertHandlerImplementations(Src : TStrings; aIndex : Integer); + +Var + cnt : Integer; + + procedure AddLn(aLine : String); + + begin + Src.Insert(aIndex+Cnt,aLine); + inc(cnt); + end; +Var + I : Integer; + N,V : String; +begin + cnt:=0; + Src.Delete(aIndex); + For I:=0 to FCommands.Count-1 do + begin + AddLn(''); + FCommands.GetNameValue(I,N,V); + AddLn('Procedure '+FPackageClassName+'.'+V+';'); + AddLn(''); + AddLn('begin'); + AddLn('end;'); + AddLn(''); + end; +end; + +Procedure TAtomPackageProjectDescriptor.InsertHandlerRegistrations(Src : TStrings; aIndex : Integer); + +Var + cnt : Integer; + + procedure AddLn(aLine : String); + + begin + Src.Insert(aIndex+Cnt,' '+aLine); + inc(cnt); + end; +Var + I : Integer; + N,V : String; + +begin + Src.Delete(aIndex); + if FCommands.Count=0 then exit; + AddLn('cmds:=TJSObject.New;'); + For I:=0 to FCommands.Count-1 do + begin + FCommands.GetNameValue(I,N,V); + AddLn('cmds['''+N+''']:=@'+V+';'); + end; + AddLn('subscriptions.add(atom.commands.add(''workspace'', cmds));'); +end; + +Procedure TAtomPackageProjectDescriptor.DoDefaultReplacements(Src : TStrings); + +Var + I,P : Integer; + +begin + For I:=Src.Count-1 downto 0 do + begin + Src[i]:=StringReplace(Src[I],'%PACKAGENAME%',FPackageName,[rfReplaceALl]); + Src[i]:=StringReplace(Src[I],'%PACKAGEPROJECTNAME%',StripNonIdentifierChars(FPackageName),[rfReplaceALl]); + Src[i]:=StringReplace(Src[I],'%CLASSNAME%',FPackageClassName,[rfReplaceALl]); + P:=pos('%PACKAGEHANDLERINTFS%',Src[i]); + if P>0 then + InsertHandlerDefinitions(Src,I,P); + P:=pos('%PACKAGEHANDLERIMPLS%',Src[i]); + if P>0 then + InsertHandlerImplementations(Src,I); + P:=pos('%PACKAGEHANDLERREGS%',Src[i]); + if P>0 then + InsertHandlerRegistrations(Src,I); + end; +end; + +function TAtomPackageProjectDescriptor.LoadDefault(Src : TStrings; aFileName : string) : boolean; + +Var + FN : String; + +begin + Result:=(PJSOptions.AtomTemplateDir<>''); + if Result then + begin + FN:=IncludeTrailingPathDelimiter(PJSOptions.AtomTemplateDir)+aFileName; + Result:=FileExists(FN); + if Result then + Src.LoadFromFile(FN); + end; +end; + +Procedure TAtomPackageProjectDescriptor.AddGlueFile(aProject : TLazProject); + +Var + Src : TStrings; + FN : String; + +begin + FN:=FPackageDir+'lib'+PathDelim+'packageglue.js'; + Src:=TStringList.Create; + try + if not LoadDefault(Src,'glue.js') then + GetDefaultGlueFile(Src); + DoDefaultReplaceMents(Src); + Src.SaveToFile(FN); + finally + Src.Free; + end; + AddFileToProject(aProject,FN); +end; + +Procedure TAtomPackageProjectDescriptor.AddCSSFile(aProject : TLazProject); + +Var + Src : TStrings; + FN : String; + +begin + FN:=FPackageDir+'styles'+PathDelim+'package.less'; + Src:=TStringList.Create; + try + if not LoadDefault(Src,'package.less') then + GetDefaultCSSFile(Src); + DoDefaultReplaceMents(Src); + Src.SaveToFile(FN); + finally + Src.Free; + end; + AddFileToProject(aProject,FN); + +end; + +Procedure TAtomPackageProjectDescriptor.AddKeyMapFile(aProject : TLazProject); + +Var + Src : TStrings; + FN : String; + +begin + FN:=FPackageDir+'keymaps'+PathDelim+'keymaps.json'; + Src:=TStringList.Create; + try + if not LoadDefault(Src,'keymaps.json') then + GetDefaultKeyMapFile(Src); + DoDefaultReplaceMents(Src); + Src.SaveToFile(FN); + finally + Src.Free; + end; + AddFileToProject(aProject,FN); +end; + +Procedure TAtomPackageProjectDescriptor.AddMenuFile(aProject : TLazProject); + +Var + Src : TStrings; + FN : String; + +begin + FN:=FPackageDir+'menus'+PathDelim+'menu.json'; + Src:=TStringList.Create; + try + if not LoadDefault(Src,'menu.json') then + GetDefaultMenuFile(Src); + DoDefaultReplaceMents(Src); + Src.SaveToFile(FN); + finally + Src.Free; + end; + AddFileToProject(aProject,FN); +end; + +Procedure TAtomPackageProjectDescriptor.AddPackageJSONFile(aProject : TLazProject); + +Var + aJSON,B : TJSONObject; + keys : TJSONArray; + S,N,V : String; + JS : TJSONStringType; + I : Integer; + aStream : TStringStream; + +begin + aJSON:=TJSONObject.Create([ + 'name',FPackagename, + 'main','lib/packageglue', + 'version','0.0.1', + 'description',FPackageDescription, + 'license',FPackageLicense + ]); + try + Keys:=TJSONArray.Create; + aJSON.add('keywords',keys); + For S in FKeyWords do + Keys.Add(S); + b:=TJSONObject.Create; + aJSON.Add('activationCommands',b); + For I:=0 to FActivationCommands.Count-1 do + begin + FActivationCommands.GetNameValue(I,N,V); + b.Add(V,FPackageName+':'+N); + end; + b:=TJSONObject.Create(['atom','>=1.0.0 <2.0.0']); + aJSON.Add('engines',b); + b:=TJSONObject.Create([]); + aJSON.Add('dependencies',b); + JS:=aJSON.FormatJSON; + aStream:=TStringStream.Create(JS); + aStream.SaveToFile(FPackageDir+'package.json'); + finally + aJSON.Free; + end; +end; + +procedure TAtomPackageProjectDescriptor.CreateProjectSource(Src : TStrings); + +begin + if not LoadDefault(Src,'project.lpr') then + GetDefaultProjectFile(Src); + DoDefaultReplaceMents(Src); +end; + +procedure TAtomPackageProjectDescriptor.AddProjectFile(AProject: TLazProject); + +Var + aFile : TLazProjectFile; + FN : String; + Src : TStrings; + +begin + FN:=FPackageDir+StripNonIdentifierChars(FPackageName)+'.lpr'; + aFile:=aProject.CreateProjectFile(FN); + AFile.IsPartOfProject:=true; + AProject.AddFile(AFile,False); + AProject.MainFileID:=0; + Src:=TStringList.Create; + try + CreateProjectSource(Src); + Src.SaveToFile(FN); + AProject.MainFile.SetSourceText(src.Text,true); + Finally + Src.Free; + end; +end; + +function TAtomPackageProjectDescriptor.InitProject(AProject: TLazProject) : TModalResult; + + +Var + CompOpts : TLazCompilerOptions; +begin + AProject.Title:=FPackageName; + AProject.ProjectInfoFile:=FPackageDir+StripNonIdentifierChars(FPackageName)+'.lpi'; + CreateProjectDirs; + CompOpts:=AProject.LazCompilerOptions; + SetDefaultNodeJSCompileOptions(CompOpts); + CompOpts.TargetFilename:='lib/'+StripNonIdentifierChars(FPackageName)+'.js'; + CompOpts.CustomOptions:='-Jiatomimports.js -Jirtl.js -Jc '+CompOpts.CustomOptions+' -Jiatomexports.js'; + SetDefaultNodeRunParams(AProject.RunParameters.GetOrCreate('Default')); + AddProjectFile(aProject); + Result:=mrOK; +end; + +Procedure TAtomPackageProjectDescriptor.AddFileToProject(aProject : TLazProject; Const aFileName : string); + +begin + LazarusIDE.DoOpenEditorFile(aFileName, -1, -1, [ofProjectLoading,ofQuiet,ofAddToProject]); +end; + +Function TAtomPackageProjectDescriptor.CreateStartFiles(AProject: TLazProject) : TModalresult; + +begin + AddGlueFile(aProject); + AddCSSFile(aProject); + AddKeyMapFile(aProject); + AddMenuFile(aProject); + AddPackageJSONFile(aProject); + Result:=mrOK; +end; + + +end. diff --git a/components/pas2js/strpas2jsdesign.pp b/components/pas2js/strpas2jsdesign.pp index 0163c5df7e..83e51ceb7b 100644 --- a/components/pas2js/strpas2jsdesign.pp +++ b/components/pas2js/strpas2jsdesign.pp @@ -35,6 +35,7 @@ Resourcestring pjsdSelectXExecutable = 'Select %s executable'; pjsdSelectNodeJSExecutable = 'Select Node.js executable'; pjsdSelectBrowserExecutable = 'Select browser executable'; + pjsdSelectAtomTemplateDir = 'Select atom package template directory'; pjsdYouCanUseIDEMacrosLikeMakeExeWithoutAFullPathIsSea = 'You can use IDE ' +'macros like $MakeExe(). Without a full path, %s is searched in PATH.'; pjsdPathOfXMacroPas2js = 'Path of %s, macro $(pas2js)';