[Developer] Add model project support

This commit is contained in:
Marc Durdin 2019-08-28 12:37:59 +10:00
parent 31cfab5abf
commit f506345f09
43 changed files with 1773 additions and 467 deletions

View file

@ -279,7 +279,10 @@ uses
Keyman.Developer.System.Project.kmnProjectFile in 'project\Keyman.Developer.System.Project.kmnProjectFile.pas',
Keyman.Developer.System.Project.modelTsProjectFileAction in 'project\Keyman.Developer.System.Project.modelTsProjectFileAction.pas',
Keyman.Developer.System.LexicalModelCompile in '..\..\global\delphi\lexicalmodels\Keyman.Developer.System.LexicalModelCompile.pas',
Keyman.Developer.UI.Project.modelTsProjectFileUI in 'project\Keyman.Developer.UI.Project.modelTsProjectFileUI.pas';
Keyman.Developer.UI.Project.modelTsProjectFileUI in 'project\Keyman.Developer.UI.Project.modelTsProjectFileUI.pas',
Keyman.Developer.System.ModelProjectTemplate in '..\kmconvert\Keyman.Developer.System.ModelProjectTemplate.pas',
Keyman.Developer.System.ProjectTemplate in '..\kmconvert\Keyman.Developer.System.ProjectTemplate.pas',
Keyman.Developer.UI.Project.UfrmNewModelProjectParameters in 'project\Keyman.Developer.UI.Project.UfrmNewModelProjectParameters.pas' {frmNewModelProjectParameters};
{$R *.RES}
{$R ICONS.RES}
@ -306,8 +309,8 @@ begin
if TikeActive then Exit;
InitClasses;
Application.CreateForm(TmodWebHttpServer, modWebHttpServer);
Application.CreateForm(TfrmKeymanDeveloper, frmKeymanDeveloper);
ShowStartup;
Application.CreateForm(TfrmKeymanDeveloper, frmKeymanDeveloper);
ShowStartup;
Application.Run;
end;
finally

View file

@ -525,6 +525,12 @@
<DCCReference Include="project\Keyman.Developer.System.Project.modelTsProjectFileAction.pas"/>
<DCCReference Include="..\..\global\delphi\lexicalmodels\Keyman.Developer.System.LexicalModelCompile.pas"/>
<DCCReference Include="project\Keyman.Developer.UI.Project.modelTsProjectFileUI.pas"/>
<DCCReference Include="..\kmconvert\Keyman.Developer.System.ModelProjectTemplate.pas"/>
<DCCReference Include="..\kmconvert\Keyman.Developer.System.ProjectTemplate.pas"/>
<DCCReference Include="project\Keyman.Developer.UI.Project.UfrmNewModelProjectParameters.pas">
<Form>frmNewModelProjectParameters</Form>
<FormType>dfm</FormType>
</DCCReference>
<None Include="Profiling\AQtimeModule1.aqt"/>
<BuildConfiguration Include="Debug">
<Key>Cfg_2</Key>

View file

@ -49,10 +49,25 @@ unit dmActionsMain; // I3306
interface
uses
System.Actions,
System.Classes,
System.ImageList,
System.SysUtils,
System.UITypes,
SysUtils, Classes, StdActns, ActnList, ImgList,
Controls, MenuImgList, KMDActions, XPStyleActnCtrls, ActnMan,
KMDActionInterfaces, Windows, System.ImageList, System.Actions;
Vcl.ActnList,
Vcl.ActnMan,
Vcl.Controls,
Vcl.ImgList,
Vcl.StdActns,
Vcl.XPStyleActnCtrls,
Winapi.Windows,
MenuImgList,
Keyman.Developer.System.Project.ProjectFile,
KMDActions,
KMDActionInterfaces,
utilfiletypes;
type
TmodActionsMain = class(TDataModule)
@ -211,6 +226,7 @@ type
procedure AboutShowStartup(Sender: TObject);
function CheckFilenameConventions(FileName: string): Boolean;
public
procedure NewProject(pt: TProjectType);
procedure OpenProject(FileName: WideString);
end;
@ -231,7 +247,6 @@ uses
Printers,
Keyman.System.KeyboardUtils,
Keyman.Developer.System.Project.Project,
Keyman.Developer.System.Project.ProjectFile,
Keyman.Developer.System.Project.ProjectFileType,
Keyman.Developer.UI.Project.ProjectFileUI,
Keyman.Developer.UI.Project.ProjectUI,
@ -261,7 +276,7 @@ uses
Keyman.Developer.UI.Project.UfrmProjectSettings,
UfrmStartup,
Upload_Settings,
utilfiletypes, UfrmMDIChild;
UfrmMDIChild;
procedure TmodActionsMain.actFileNewExecute(Sender: TObject);
var
@ -537,12 +552,21 @@ begin
FGlobalProject.Save;
FreeGlobalProjectUI;
LoadGlobalProjectUI(FileName); // I4687
LoadGlobalProjectUI(ptUnknown, FileName); // I4687
frmKeymanDeveloper.ProjectMRU.Add(FGlobalProject.FileName);
frmKeymanDeveloper.ShowProject;
frmKeymanDeveloper.UpdateCaption;
end;
procedure TmodActionsMain.NewProject(pt: TProjectType);
begin
FGlobalProject.Save;
FreeGlobalProjectUI;
LoadGlobalProjectUI(pt, '', False); // I4687
frmKeymanDeveloper.ShowProject;
frmKeymanDeveloper.UpdateCaption;
end;
procedure TmodActionsMain.actProjectSaveAsAccept(Sender: TObject);
begin
FGlobalProject.FileName := actProjectSaveAs.Dialog.FileName;

View file

@ -23,6 +23,7 @@ const
SHelpTopic_Context_New = 'context/new';
SHelpTopic_Context_NewProject = 'context/new-project';
SHelpTopic_Context_NewProjectParameters = 'context/new-project-parameters';
SHelpTopic_Context_NewModelProjectParameters = 'context/new-model-project-parameters';
SHelpTopic_Context_NewFileDetails = 'context/new-file-details';
SHelpTopic_Context_OnScreenKeyboardEditor = 'context/keyboard-editor#toc-on-screen-tab';
SHelpTopic_Context_Options = 'context/options';

View file

@ -118,7 +118,7 @@ procedure TAppHttpResponder.RespondProject(doc: string; AContext: TIdContext;
end;
// Transform the .kpj
with TProject.Create(path) do
with TProject.Create(ptUnknown, path) do
try
AResponseInfo.ContentType := 'text/html; charset=UTF-8';
AResponseInfo.ContentText := Render;

View file

@ -614,7 +614,7 @@ end;
procedure TframeCEFHost.cefSetFocus(Sender: TObject; const browser: ICefBrowser;
source: TCefFocusSource; out Result: Boolean);
begin
Result := source = FOCUS_SOURCE_NAVIGATION;
Result := source <> FOCUS_SOURCE_NAVIGATION;
end;
procedure TframeCEFHost.WMEnterMenuLoop(var aMessage: TMessage);

View file

@ -517,7 +517,7 @@ begin
if (FActiveProject <> '') and not FileExists(FActiveProject) then
FActiveProject := '';
LoadGlobalProjectUI(FActiveProject, True);
LoadGlobalProjectUI(ptUnknown, FActiveProject, True);
InitDock;

View file

@ -79,7 +79,8 @@ uses
mrulist,
Keyman.Developer.System.Project.ProjectLog,
TempFileManager;
TempFileManager,
utilfiletypes;
type
{ Forward declarations }
@ -92,6 +93,7 @@ type
TProjectOptions = class;
TProjectState = (psCreating, psReady, psLoading, psSaving, psDestroying);
TProjectType = (ptUnknown, ptKeyboard, ptLexicalModel); // distinct from utilfiletypes.TKeymanProjectType
{ TProject }
@ -134,7 +136,7 @@ type
public
procedure Log(AState: TProjectLogState; Filename, Msg: string); virtual;
constructor Create(AFileName: string; ALoadPersistedUntitledProject: Boolean = False); virtual;
constructor Create(AProjectType: TProjectType; AFileName: string; ALoadPersistedUntitledProject: Boolean = False); virtual;
destructor Destroy; override;
procedure Refresh;
@ -295,12 +297,14 @@ type
FWarnDeprecatedCode: Boolean; // I4866
FCompilerWarningsAsErrors: Boolean; // I4865
FCheckFilenameConventions: Boolean;
FProjectType: TProjectType;
public
constructor Create;
property BuildPath: string read FBuildPath write FBuildPath;
property WarnDeprecatedCode: Boolean read FWarnDeprecatedCode write FWarnDeprecatedCode; // I4866
property CompilerWarningsAsErrors: Boolean read FCompilerWarningsAsErrors write FCompilerWarningsAsErrors; // I4865
property CheckFilenameConventions: Boolean read FCheckFilenameConventions write FCheckFilenameConventions;
property ProjectType: TProjectType read FProjectType write FProjectType;
end;
const
@ -310,6 +314,9 @@ function GlobalProjectStateWndHandle: THandle;
function ProjectCompilerMessage(line: Integer; msgcode: LongWord; text: PAnsiChar): Integer; stdcall; // I3310 // I4694
procedure ProjectCompilerMessageClear;
function ProjectTypeFromString(s: string): TProjectType;
function ProjectTypeToString(pt: TProjectType): string;
implementation
uses
@ -330,7 +337,6 @@ uses
UMD5Hash,
Unicode,
utildir,
utilfiletypes,
utilsystem;
{ TProjectFileList }
@ -679,11 +685,16 @@ begin
end;
end;
constructor TProject.Create(AFileName: string; ALoadPersistedUntitledProject: Boolean = False);
constructor TProject.Create(AProjectType: TProjectType; AFileName: string; ALoadPersistedUntitledProject: Boolean = False);
var
i: Integer;
begin
FOptions := TProjectOptions.Create; // I4688
if AProjectType = ptUnknown
then FOptions.ProjectType := ptKeyboard
else FOptions.ProjectType := AProjectType;
FState := psCreating;
inherited Create;
FMRU := TMRUList.Create('');
@ -1201,6 +1212,7 @@ begin
WarnDeprecatedCode := True; // I4866
CompilerWarningsAsErrors := False; // I4865
CheckFilenameConventions := True; // default to TRUE for new projects
ProjectType := ptKeyboard;
end;
type
@ -1262,6 +1274,22 @@ begin
Result := FGlobalProjectStateWndHandle;
end;
function ProjectTypeFromString(s: string): TProjectType;
begin
if SameText(s, 'keyboard') then Result := ptKeyboard
else if SameText(s, 'lexicalmodel') then Result := ptLexicalModel
else Result := ptUnknown;
end;
function ProjectTypeToString(pt: TProjectType): string;
begin
case pt of
ptUnknown: Result := '';
ptKeyboard: Result := 'keyboard';
ptLexicalModel: Result := 'lexicalmodel';
end;
end;
initialization
FGlobalProjectStateWnd := TGlobalProjectStateWnd.Create;
finalization

View file

@ -73,6 +73,7 @@ begin
FFileName := AFileName;
end;
procedure TProjectLoader.Execute; // I4698
var
n, i: Integer;
@ -109,6 +110,11 @@ begin
if VarIsNull(node.ChildValues['CheckFilenameConventions'])
then FProject.Options.CheckFilenameConventions := False // existing projects default to FALSE (new projects default to TRUE)
else FProject.Options.CheckFilenameConventions := node.ChildValues['CheckFilenameConventions'];
FProject.Options.ProjectType := ProjectTypeFromString(VarToStr(node.ChildValues['ProjectType']));
if FProject.Options.ProjectType = ptUnknown then
// Support projects without a defined projecttype
FProject.Options.ProjectType := ptKeyboard;
end;
{ Load root nodes first - I708 }

View file

@ -96,6 +96,7 @@ begin
node.AddChild('CompilerWarningsAsErrors').NodeValue := FProject.Options.CompilerWarningsAsErrors; // I4866
node.AddChild('WarnDeprecatedCode').NodeValue := FProject.Options.WarnDeprecatedCode; // I4865
node.AddChild('CheckFilenameConventions').NodeValue := FProject.Options.CheckFilenameConventions; // I4866
node.AddChild('ProjectType').NodeValue := ProjectTypeToString(FProject.Options.ProjectType);
// files

View file

@ -50,7 +50,7 @@ type
procedure DoRefreshCaption; override;
public
constructor Create(AFileName: string; ALoadPersistedUntitledProject: Boolean = False); override;
constructor Create(AProjectType: TProjectType; AFileName: string; ALoadPersistedUntitledProject: Boolean = False); override;
destructor Destroy; override;
procedure Log(AState: TProjectLogState; Filename, Msg: string); override; // I4706
@ -135,7 +135,7 @@ end;
{ TProjectUI }
constructor TProjectUI.Create(AFileName: string;
constructor TProjectUI.Create(AProjectType: TProjectType; AFileName: string;
ALoadPersistedUntitledProject: Boolean);
begin
inherited;

View file

@ -21,10 +21,11 @@ unit Keyman.Developer.UI.Project.ProjectUI; // I4687
interface
uses
Keyman.Developer.System.Project.ProjectFile,
Keyman.Developer.UI.Project.ProjectFileUI;
function GetGlobalProjectUI: TProjectUI;
function LoadGlobalProjectUI(AFilename: string; ALoadPersistedUntitledProject: Boolean = False): TProjectUI;
function LoadGlobalProjectUI(pt: TProjectType; AFilename: string; ALoadPersistedUntitledProject: Boolean = False): TProjectUI;
procedure FreeGlobalProjectUI;
implementation
@ -44,10 +45,10 @@ begin
FreeAndNil(FGlobalProject);
end;
function LoadGlobalProjectUI(AFilename: string; ALoadPersistedUntitledProject: Boolean = False): TProjectUI;
function LoadGlobalProjectUI(pt: TProjectType; AFilename: string; ALoadPersistedUntitledProject: Boolean = False): TProjectUI;
begin
Assert(not Assigned(FGlobalProject));
Result := TProjectUI.Create(AFilename, ALoadPersistedUntitledProject); // I4687
Result := TProjectUI.Create(pt, AFilename, ALoadPersistedUntitledProject); // I4687
FGlobalProject := Result;
end;

View file

@ -0,0 +1,243 @@
inherited frmNewModelProjectParameters: TfrmNewModelProjectParameters
BorderIcons = [biSystemMenu]
BorderStyle = bsDialog
Caption = 'New Wordlist Lexical Model Project'
ClientHeight = 309
ClientWidth = 625
OldCreateOrder = True
Position = poScreenCenter
OnDestroy = FormDestroy
ExplicitWidth = 631
ExplicitHeight = 338
DesignSize = (
625
309)
PixelsPerInch = 96
TextHeight = 13
object lblFileName: TLabel
Left = 12
Top = 275
Width = 46
Height = 13
Caption = '&Model ID:'
FocusControl = editModelID
end
object lblPath: TLabel
Left = 12
Top = 248
Width = 26
Height = 13
Caption = '&Path:'
FocusControl = editPath
end
object lblAuthorID: TLabel
Left = 12
Top = 11
Width = 51
Height = 13
Caption = 'Aut&hor ID:'
FocusControl = editAuthorID
end
object lblCoypright: TLabel
Left = 12
Top = 113
Width = 51
Height = 13
Caption = '&Copyright:'
FocusControl = editCopyright
end
object lblVersion: TLabel
Left = 12
Top = 140
Width = 39
Height = 13
Caption = '&Version:'
FocusControl = editVersion
end
object lblAuthor: TLabel
Left = 12
Top = 167
Width = 67
Height = 13
Caption = 'A&uthor Name:'
FocusControl = editAuthor
end
object lblKeyboardLanguages: TLabel
Left = 339
Top = 11
Width = 52
Height = 13
Caption = '&Languages'
FocusControl = gridKeyboardLanguages
end
object lblBCP47: TLabel
Left = 12
Top = 38
Width = 95
Height = 13
Caption = 'Primary BCP47 &Tag:'
end
object lblUniq: TLabel
Left = 12
Top = 65
Width = 67
Height = 13
Caption = 'Uni&que Name:'
FocusControl = editUniq
end
object editModelID: TEdit
Left = 120
Top = 272
Width = 149
Height = 21
ParentColor = True
ReadOnly = True
TabOrder = 11
OnChange = editModelIDChange
end
object cmdBrowse: TButton
Left = 275
Top = 272
Width = 78
Height = 21
Caption = '&Browse...'
TabOrder = 12
OnClick = cmdBrowseClick
end
object editPath: TEdit
Left = 120
Top = 245
Width = 233
Height = 21
TabOrder = 10
OnChange = editPathChange
end
object editAuthorID: TEdit
Left = 120
Top = 8
Width = 205
Height = 21
TabOrder = 0
OnChange = editModelIDComponentChange
end
object editCopyright: TEdit
Left = 120
Top = 110
Width = 205
Height = 21
TabOrder = 3
Text = #169
OnChange = editCopyrightChange
end
object editVersion: TEdit
Left = 120
Top = 137
Width = 205
Height = 21
TabOrder = 4
Text = '1.0'
OnChange = editVersionChange
end
object editAuthor: TEdit
Left = 120
Top = 164
Width = 205
Height = 21
TabOrder = 5
OnChange = editAuthorChange
end
object cmdOK: TButton
Left = 463
Top = 270
Width = 73
Height = 25
Caption = 'OK'
Default = True
TabOrder = 13
OnClick = cmdOKClick
end
object cmdCancel: TButton
Left = 542
Top = 270
Width = 73
Height = 25
Cancel = True
Caption = 'Cancel'
ModalResult = 2
TabOrder = 14
end
object gridKeyboardLanguages: TStringGrid
Left = 339
Top = 32
Width = 278
Height = 153
Anchors = [akLeft, akTop, akRight, akBottom]
ColCount = 2
DefaultRowHeight = 16
FixedCols = 0
RowCount = 9
Options = [goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine, goColSizing, goRowSelect]
TabOrder = 6
OnClick = gridKeyboardLanguagesClick
OnDblClick = gridKeyboardLanguagesDblClick
ColWidths = (
78
64)
end
object cmdKeyboardAddLanguage: TButton
Left = 340
Top = 191
Width = 73
Height = 25
Anchors = [akLeft, akBottom]
Caption = '&Add...'
TabOrder = 7
OnClick = cmdKeyboardAddLanguageClick
end
object cmdKeyboardEditLanguage: TButton
Left = 419
Top = 191
Width = 73
Height = 25
Anchors = [akLeft, akBottom]
Caption = 'Ed&it...'
TabOrder = 8
OnClick = cmdKeyboardEditLanguageClick
end
object cmdKeyboardRemoveLanguage: TButton
Left = 498
Top = 191
Width = 72
Height = 25
Anchors = [akLeft, akBottom]
Caption = '&Remove'
TabOrder = 9
OnClick = cmdKeyboardRemoveLanguageClick
end
object editUniq: TEdit
Left = 120
Top = 62
Width = 205
Height = 21
TabOrder = 2
OnChange = editModelIDComponentChange
end
object cbBCP47: TComboBox
Left = 120
Top = 35
Width = 205
Height = 21
Style = csDropDownList
TabOrder = 1
OnClick = editModelIDComponentChange
end
object dlgSave: TSaveDialog
DefaultExt = 'kpj'
Filter = 'Project files (*.kpj)|*.kpj|All files (*.*)|*.*'
FilterIndex = 0
Title = 'Create New Project'
OnCanClose = dlgSaveCanClose
Left = 396
Top = 240
end
end

View file

@ -0,0 +1,514 @@
unit Keyman.Developer.UI.Project.UfrmNewModelProjectParameters;
interface
uses
System.Classes,
System.SysUtils,
System.UITypes,
System.Variants,
Winapi.Messages,
Winapi.Windows,
Vcl.CheckLst,
Vcl.Controls,
Vcl.Dialogs,
Vcl.Forms,
Vcl.Graphics,
Vcl.Grids,
Vcl.StdCtrls,
kpsfile,
PackageInfo,
UfrmTike,
utilfiletypes;
type
TfrmNewModelProjectParameters = class(TTikeForm)
lblFileName: TLabel;
lblPath: TLabel;
lblAuthorID: TLabel;
lblCoypright: TLabel;
lblVersion: TLabel;
lblAuthor: TLabel;
lblKeyboardLanguages: TLabel;
editModelID: TEdit;
cmdBrowse: TButton;
editPath: TEdit;
editAuthorID: TEdit;
editCopyright: TEdit;
editVersion: TEdit;
editAuthor: TEdit;
cmdOK: TButton;
cmdCancel: TButton;
gridKeyboardLanguages: TStringGrid;
cmdKeyboardAddLanguage: TButton;
cmdKeyboardEditLanguage: TButton;
cmdKeyboardRemoveLanguage: TButton;
dlgSave: TSaveDialog;
lblBCP47: TLabel;
lblUniq: TLabel;
editUniq: TEdit;
cbBCP47: TComboBox;
procedure cmdOKClick(Sender: TObject);
procedure editModelIDComponentChange(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure gridKeyboardLanguagesClick(Sender: TObject);
procedure gridKeyboardLanguagesDblClick(Sender: TObject);
procedure cmdKeyboardAddLanguageClick(Sender: TObject);
procedure cmdKeyboardEditLanguageClick(Sender: TObject);
procedure cmdKeyboardRemoveLanguageClick(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure editCopyrightChange(Sender: TObject);
procedure editVersionChange(Sender: TObject);
procedure editAuthorChange(Sender: TObject);
procedure editPathChange(Sender: TObject);
procedure editModelIDChange(Sender: TObject);
procedure cmdBrowseClick(Sender: TObject);
procedure dlgSaveCanClose(Sender: TObject; var CanClose: Boolean);
private
pack: TKPSFile;
FSetup: Integer;
function GetAuthor: string;
function GetBasePath: string;
function GetCopyright: string;
function GetBCP47Tags: string;
function GetVersion: string;
function Validate: Boolean;
procedure EnableControls;
function SelectedKeyboardLanguage: TPackageKeyboardLanguage;
procedure LanguageGrid_Fill;
procedure BCP47_Fill;
function SelectedLexicalModel: TPackageLexicalModel;
function GetModelID: string;
protected
function GetHelpTopic: string; override;
public
property Copyright: string read GetCopyright;
property Version: string read GetVersion;
property Author: string read GetAuthor;
property BCP47Tags: string read GetBCP47Tags;
property BasePath: string read GetBasePath;
property ModelID: string read GetModelID;
end;
function ShowNewModelProjectParameters(Owner: TComponent): Boolean;
implementation
uses
Winapi.ShlObj,
Keyman.System.LanguageCodeUtils,
Keyman.System.LexicalModelUtils,
BCP47Tag,
utilstr,
utilsystem,
dmActionsMain,
Keyman.Developer.System.HelpTopics,
Keyman.Developer.System.Project.Project,
Keyman.Developer.System.Project.ProjectFile,
Keyman.Developer.System.KeyboardProjectTemplate,
Keyman.Developer.System.ModelProjectTemplate,
Keyman.Developer.System.ProjectTemplate,
Keyman.Developer.UI.UfrmSelectBCP47Language;
// 1. project filename
// 2. location
// 3. keyboard name
// 4. copyright
// 5. targets
// 6. author
// 7. version
// 8. bcp47 tags
{$R *.dfm}
function ShowNewModelProjectParameters(Owner: TComponent): Boolean;
var
f: TfrmNewModelProjectParameters;
pt: TProjectTemplate;
begin
f := TfrmNewModelProjectParameters.Create(Owner);
try
Result := f.ShowModal = mrOk;
if not Result then
Exit;
pt := TModelProjectTemplate.Create(f.BasePath, f.ModelID);
try
pt.Name := f.ModelID;
pt.Copyright := f.Copyright;
pt.Author := f.Author;
pt.Version := f.Version;
pt.BCP47Tags := f.BCP47Tags;
try
pt.Generate;
except
on E:EFOpenError do
begin
ShowMessage('Unable to create project: '+E.Message);
Exit(False);
end;
end;
modActionsMain.OpenProject(pt.ProjectFilename);
Result := True;
finally
pt.Free;
end;
finally
f.Free;
end;
end;
{ TfrmNewModelProjectParameters }
procedure TfrmNewModelProjectParameters.FormCreate(Sender: TObject);
begin
inherited;
editPath.Text := GetFolderPath(CSIDL_PERSONAL);
pack := TKPSFile.Create;
pack.LexicalModels.Add(TPackageLexicalModel.Create(pack));
LanguageGrid_Fill;
EnableControls;
end;
procedure TfrmNewModelProjectParameters.FormDestroy(Sender: TObject);
begin
inherited;
FreeAndNil(pack);
end;
procedure TfrmNewModelProjectParameters.BCP47_Fill;
var
lm: TPackageLexicalModel;
FLastBCP47: string;
lang: TPackageKeyboardLanguage;
begin
FLastBCP47 := cbBCP47.Text;
cbBCP47.Clear;
lm := SelectedLexicalModel;
if not Assigned(lm) then
Exit;
for lang in lm.Languages do
cbBCP47.Items.Add(lang.ID);
cbBCP47.ItemIndex := cbBCP47.Items.IndexOf(FLastBCP47);
if (cbBCP47.ItemIndex < 0) and (cbBCP47.Items.Count > 0) then
cbBCP47.ItemIndex := 0;
editModelIDComponentChange(cbBCP47);
end;
procedure TfrmNewModelProjectParameters.cmdBrowseClick(Sender: TObject);
var
FPathName, FFolderName, FProjectName: string;
begin
inherited;
if dlgSave.Execute then
begin
FPathName := ExtractFilePath(ExtractFileDir(dlgSave.FileName));
FFolderName := ExtractFileName(ExtractFileDir(dlgSave.FileName));
FProjectName := ChangeFileExt(ExtractFileName(dlgSave.FileName), '');
if not SameText(FFolderName, FProjectName) then
begin
if MessageDlg('The project will be saved at "'+FPathName+FFolderName+'\'+FProjectName+'\'+FProjectName+'.kpj". Continue?',
mtConfirmation, mbOkCancel, 0) = mrCancel then
Exit;
FPathName := FPathName+FFolderName;
end;
editPath.Text := ExcludeTrailingPathDelimiter(FPathName);
editModelID.Text := FProjectName;
end;
end;
procedure TfrmNewModelProjectParameters.cmdKeyboardAddLanguageClick(
Sender: TObject);
var
lm: TPackageLexicalModel;
lang: TPackageKeyboardLanguage;
frm: TfrmSelectBCP47Language;
begin
lm := SelectedLexicalModel;
Assert(Assigned(lm));
frm := TfrmSelectBCP47Language.Create(Self);
try
if frm.ShowModal = mrOk then
begin
lang := TPackageKeyboardLanguage.Create(pack);
lang.ID := frm.LanguageID;
lang.Name := frm.LanguageName;
lm.Languages.Add(lang);
BCP47_Fill;
LanguageGrid_Fill;
gridKeyboardLanguages.Row := gridKeyboardLanguages.RowCount - 1;
gridKeyboardLanguagesClick(gridKeyboardLanguages);
EnableControls;
end;
finally
frm.Free;
end;
end;
procedure TfrmNewModelProjectParameters.cmdKeyboardEditLanguageClick(
Sender: TObject);
var
lm: TPackageLexicalModel;
lang: TPackageKeyboardLanguage;
frm: TfrmSelectBCP47Language;
begin
lm := SelectedLexicalModel;
Assert(Assigned(lm));
lang := SelectedKeyboardLanguage;
Assert(Assigned(lang));
frm := TfrmSelectBCP47Language.Create(Self);
try
frm.LanguageID := lang.ID;
frm.LanguageName := lang.Name;
if frm.ShowModal = mrOk then
begin
lang.ID := frm.LanguageID;
lang.Name := frm.LanguageName;
BCP47_Fill;
LanguageGrid_Fill;
EnableControls;
end;
finally
frm.Free;
end;
end;
procedure TfrmNewModelProjectParameters.cmdKeyboardRemoveLanguageClick(
Sender: TObject);
var
lm: TPackageLexicalModel;
lang: TPackageKeyboardLanguage;
begin
lm := SelectedLexicalModel;
Assert(Assigned(lm));
lang := SelectedKeyboardLanguage;
Assert(Assigned(lang));
lm.Languages.Remove(lang);
LanguageGrid_Fill;
BCP47_Fill;
EnableControls;
end;
procedure TfrmNewModelProjectParameters.cmdOKClick(Sender: TObject);
begin
if Validate then
ModalResult := mrOk;
end;
procedure TfrmNewModelProjectParameters.dlgSaveCanClose(Sender: TObject; var CanClose: Boolean);
begin
if not TLexicalModelUtils.DoesProjectFilenameFollowLexicalModelConventions(dlgSave.FileName) then
begin
CanClose := False;
ShowMessage(Format(TLexicalModelUtils.SProjectFileNameDoesNotFollowLexicalModelConventions_Message, [ExtractFileName(dlgSave.FileName)]));
end
else
CanClose := True;
end;
procedure TfrmNewModelProjectParameters.editAuthorChange(Sender: TObject);
begin
EnableControls;
end;
procedure TfrmNewModelProjectParameters.editCopyrightChange(Sender: TObject);
begin
EnableControls;
end;
procedure TfrmNewModelProjectParameters.editModelIDChange(Sender: TObject);
begin
EnableControls;
end;
procedure TfrmNewModelProjectParameters.editModelIDComponentChange(Sender: TObject);
begin
editModelID.Text := Format('%s.%s.%s', [editAuthorID.Text, cbBCP47.Text, editUniq.Text]);
EnableControls;
end;
procedure TfrmNewModelProjectParameters.editPathChange(Sender: TObject);
begin
EnableControls;
end;
procedure TfrmNewModelProjectParameters.editVersionChange(Sender: TObject);
begin
EnableControls;
end;
procedure TfrmNewModelProjectParameters.EnableControls;
var
e: Boolean;
begin
e :=
(Trim(editAuthorID.Text) <> '') and
(Trim(cbBCP47.Text) <> '') and
(Trim(editUniq.Text) <> '') and
(Trim(editPath.Text) <> '') and
TLexicalModelUtils.DoesProjectFilenameFollowLexicalModelConventions(editModelID.Text + Ext_LexicalModelProject) and
(pack.LexicalModels[0].Languages.Count > 0);
cmdOK.Enabled := e;
e := gridKeyboardLanguages.RowCount > 1;
gridKeyboardLanguages.Enabled := e;
cmdKeyboardRemoveLanguage.Enabled := e;
cmdKeyboardEditLanguage.Enabled := e;
if e then
gridKeyboardLanguages.FixedRows := 1;
end;
function TfrmNewModelProjectParameters.GetAuthor: string;
begin
Result := Trim(editAuthor.Text);
end;
function TfrmNewModelProjectParameters.GetBasePath: string;
begin
Result := Trim(editPath.Text);
end;
function TfrmNewModelProjectParameters.GetCopyright: string;
begin
Result := Trim(editCopyright.Text);
end;
function TfrmNewModelProjectParameters.GetHelpTopic: string;
begin
Result := SHelpTopic_Context_NewModelProjectParameters;
end;
function TfrmNewModelProjectParameters.GetModelID: string;
begin
Result := editModelID.Text;
end;
function TfrmNewModelProjectParameters.GetBCP47Tags: string;
var
lang: TPackageKeyboardLanguage;
begin
Result := '';
for lang in pack.LexicalModels[0].Languages do
Result := Result + lang.ID + ' ';
Result := Result.Trim;
end;
function TfrmNewModelProjectParameters.GetVersion: string;
begin
Result := Trim(editVersion.Text);
end;
procedure TfrmNewModelProjectParameters.gridKeyboardLanguagesClick(
Sender: TObject);
begin
EnableControls;
end;
procedure TfrmNewModelProjectParameters.gridKeyboardLanguagesDblClick(
Sender: TObject);
begin
if SelectedKeyboardLanguage <> nil then
cmdKeyboardEditLanguage.Click;
end;
function TfrmNewModelProjectParameters.Validate: Boolean;
var
ProjectFolder: string;
begin
Result := TLexicalModelUtils.DoesProjectFilenameFollowLexicalModelConventions(editModelID.Text + Ext_LexicalModelProject);
if Result then
begin
if not DirectoryExists(editPath.Text) then
begin
if MessageDlg('The target folder '+editPath.Text+' does not exist. Create it now?', mtConfirmation, mbOkCancel, 0) = mrCancel then
Exit(False);
end;
ProjectFolder := IncludeTrailingPathDelimiter(editPath.Text) + editModelID.Text;
if DirectoryExists(ProjectFolder) then
begin
if MessageDlg('The project folder '+ProjectFolder+' already exists. Are you sure you want to overwrite it?', mtWarning,
mbOkCancel, 0) = mrCancel then
Exit(False);
end;
end;
end;
{ Languages Grid }
function TfrmNewModelProjectParameters.SelectedLexicalModel: TPackageLexicalModel;
begin
Result := pack.LexicalModels[0];
end;
function TfrmNewModelProjectParameters.SelectedKeyboardLanguage: TPackageKeyboardLanguage;
var
lm: TPackageLexicalModel;
begin
lm := SelectedLexicalModel;
if not Assigned(lm) then
Exit(nil);
if gridKeyboardLanguages.Row = 0 then
Exit(nil);
Result := gridKeyboardLanguages.Objects[0, gridKeyboardLanguages.Row] as TPackageKeyboardLanguage;
end;
procedure TfrmNewModelProjectParameters.LanguageGrid_Fill;
var
lm: TPackageLexicalModel;
i: Integer;
begin
Inc(FSetup);
try
gridKeyboardLanguages.Cells[0, 0] := 'BCP 47 tag';
gridKeyboardLanguages.Cells[1, 0] := 'Language name';
gridKeyboardLanguages.ColWidths[0] := 120;
gridKeyboardLanguages.ColWidths[1] := 10;
lm := SelectedLexicalModel;
if not Assigned(lm) then
begin
gridKeyboardLanguages.RowCount := 1;
EnableControls;
Exit;
end;
gridKeyboardLanguages.RowCount := lm.Languages.Count + 1;
gridKeyboardLanguages.ColWidths[1] := gridKeyboardLanguages.ClientWidth - 120 - 1;
for i := 0 to lm.Languages.Count - 1 do
begin
gridKeyboardLanguages.Objects[0, i+1] := lm.Languages[i];
gridKeyboardLanguages.Cells[0, i+1] := lm.Languages[i].ID;
gridKeyboardLanguages.Cells[1, i+1] := lm.Languages[i].Name;
end;
EnableControls;
finally
Dec(FSetup);
end;
end;
end.

View file

@ -42,11 +42,15 @@ inherited frmNewProject: TfrmNewProject
FullDrag = True
HideSelection = False
Items.ItemData = {
05900000000300000001000000FFFFFFFFFFFFFFFF00000000FFFFFFFF000000
05160100000500000001000000FFFFFFFFFFFFFFFF00000000FFFFFFFF000000
00054200610073006900630000000000FFFFFFFFFFFFFFFF00000000FFFFFFFF
000000000542006C0061006E006B0000000000FFFFFFFFFFFFFFFF00000000FF
FFFFFF000000001749006D0070006F00720074002000570069006E0064006F00
7700730020004B006500790062006F00610072006400}
000000000542006C0061006E006B0002000000FFFFFFFFFFFFFFFF00000000FF
FFFFFF000000001657006F00720064006C0069007300740020004C0065007800
6900630061006C0020004D006F00640065006C0000000000FFFFFFFFFFFFFFFF
00000000FFFFFFFF000000001342006C0061006E006B0020004C006500780069
00630061006C0020004D006F00640065006C0000000000FFFFFFFFFFFFFFFF00
000000FFFFFFFF000000001749006D0070006F00720074002000570069006E00
64006F007700730020004B006500790062006F00610072006400}
LargeImages = ilLarge
SmallImages = ilSmall
TabOrder = 0
@ -82,7 +86,7 @@ inherited frmNewProject: TfrmNewProject
Left = 56
Top = 292
Bitmap = {
494C010102000800280020002000FFFFFF002110FFFFFFFFFFFFFFFF424D3600
494C0101030008003C0020002000FFFFFF002110FFFFFFFFFFFFFFFF424D3600
0000000000003600000028000000800000002000000001002000000000000040
0000000000000000000000000000000000000000000000000000000000000000
00004D4D4DAFB2B2B1F9B2B2B1F9B1B1B0F8B1B1B0F8B1B1B0F8B1B1B0F8B1B1
@ -140,11 +144,11 @@ inherited frmNewProject: TfrmNewProject
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000176ABEFF3683CCFF3683CCFF3683
CCFF3683CCFF3683CCFF3683CCFF1166BCFF3683CCFF3683CCFF3683CCFF3683
CCFF3683CCFF3683CCFF3683CCFF3683CCFF3683CCFF3683CCFF3683CCFF3683
CCFF3683CCFF3683CCFF3683CCFF3683CCFF1F70C2FF3481CBFF3683CCFF3683
CCFF3683CCFF3683CCFF3683CCFF1166BCFF0000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
@ -156,11 +160,11 @@ inherited frmNewProject: TfrmNewProject
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000001469BDFF307DC9FF307DC9FF307D
C9FF307DC9FF307DC9FF307DC9FF0F65BBFF307DC9FF307DC9FF307DC9FF307D
C9FF307DC9FF307DC9FF307DC9FF307DC9FF307DC9FF307DC9FF307DC9FF307D
C9FF307DC9FF307DC9FF307DC9FF307DC9FF1B6EC0FF2F7CC8FF307DC9FF307D
C9FF307DC9FF307DC9FF307DC9FF0F65BBFF0000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
@ -172,11 +176,11 @@ inherited frmNewProject: TfrmNewProject
000000000000000000000000000000000000000000000000000000000003001E
3D9000468DE000060D4600000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000004A91D4FFAFDBFFFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFF3783CCFFAFDBFFFFAFDBFFFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFF63A4DFFFA9D6FCFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFF3783CCFF0000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
@ -188,11 +192,11 @@ inherited frmNewProject: TfrmNewProject
0000000000000000000000000000000000000000000000040837004080CD007D
EDFC004E9CEB004994E8001A378D000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000004A91D4FFAFDBFFFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFF3783CCFFAFDBFFFFAFDBFFFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFF63A4DFFFA9D6FCFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFF3783CCFF0000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
@ -204,11 +208,11 @@ inherited frmNewProject: TfrmNewProject
00000000000000000000000000000000000500224599005CB4E70088FEFF0087
FFFF004D9EEE0057B3FF0055AAF8003366C00000011500000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000003582CBFF7CB6EAFF7CB6EAFF7CB6
EAFF7CB6EAFF7CB6EAFF7CB6EAFF2777C5FF7CB6EAFF7CB6EAFF7CB6EAFF7CB6
EAFF7CB6EAFF7CB6EAFF7CB6EAFF7CB6EAFF7CB6EAFF7CB6EAFF7CB6EAFF7CB6
EAFF7CB6EAFF7CB6EAFF7CB6EAFF7CB6EAFF478FD3FF78B3E8FF7CB6EAFF7CB6
EAFF7CB6EAFF7CB6EAFF7CB6EAFF2777C5FF0000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
@ -220,11 +224,11 @@ inherited frmNewProject: TfrmNewProject
0000000000000000000000050B3F004284D00080F1FD0088FFFF007FF4FE035A
AFEE0C59A8F30051A3F40058B3FF0059B4FF004081D800070F4B000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000003D88CFFF91C5F2FF91C5F2FF91C5
F2FF91C5F2FF91C5F2FF91C5F2FF2E7BC8FF91C5F2FF91C5F2FF91C5F2FF91C5
F2FF91C5F2FF91C5F2FF91C5F2FF91C5F2FF91C5F2FF91C5F2FF91C5F2FF91C5
F2FF91C5F2FF91C5F2FF91C5F2FF91C5F2FF5297D8FF8CC1F0FF91C5F2FF91C5
F2FF91C5F2FF91C5F2FF91C5F2FF2E7BC8FF0000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
@ -236,11 +240,11 @@ inherited frmNewProject: TfrmNewProject
00000000000800264BA00061BBEA0088FFFF0087FEFF0063C1F0115DAAED9CCC
F7FFAFDBFFFF3F83C1F401509EF00057B2FF0058B3FF004A96E9001D3A920000
0001000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000004A91D4FFAFDBFFFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFF3783CCFFAFDBFFFFAFDBFFFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFF63A4DFFFA9D6FCFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFF3783CCFF0000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
@ -252,11 +256,11 @@ inherited frmNewProject: TfrmNewProject
0E48004589D30081F5FE0087FFFF0079EAFB0459ABEE5592C9F2ACD9FEFF3C8C
D5FF1C71C3FF9FD0F8FF84BAECFE0655A4F20055AEFC0058B4FF0055ACF90033
68C2000001170000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000004A91D4FFAFDBFFFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFF3783CCFFAFDBFFFFAFDBFFFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFF63A4DFFFA9D6FCFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFF3783CCFF0000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
@ -268,11 +272,11 @@ inherited frmNewProject: TfrmNewProject
C2EC0088FFFF0085FDFF005EB9EE1A63AAECA5D3FAFF82BBEEFF1875CDFF007D
F3FF1A77D3FF0A62B9FF6FACE3FFA9D7FDFF1962ABF1004FA0F20057B3FF0059
B4FF004183DA0008114F00000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000003783CCFF82BAECFF82BAECFF82BA
ECFF82BAECFF82BAECFF82BAECFF2978C6FF82BAECFF82BAECFF82BAECFF82BA
ECFF82BAECFF82BAECFF82BAECFF82BAECFF82BAECFF82BAECFF82BAECFF82BA
ECFF82BAECFF82BAECFF82BAECFF82BAECFF4991D4FF7DB7EAFF82BAECFF82BA
ECFF82BAECFF82BAECFF82BAECFF2978C6FF0000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
@ -284,11 +288,11 @@ inherited frmNewProject: TfrmNewProject
FFFF0072DCF6065AABEE6CA4D6F6A8D5FCFF2E84D3FF136DC5FF0A87F7FF0088
FFFF2185E3FF0E63B9FF025AB4FF3983CCFFAFDBFFFF4C8BC7F50150A0F10057
B2FF0058B3FF004A96EA001F3D96000000010000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000003C87CEFF8DC2F1FF8DC2F1FF8DC2
F1FF8DC2F1FF8DC2F1FF8DC2F1FF2C7BC7FF8DC2F1FF8DC2F1FF8DC2F1FF8DC2
F1FF8DC2F1FF8DC2F1FF8DC2F1FF8DC2F1FF8DC2F1FF8DC2F1FF8DC2F1FF8DC2
F1FF8DC2F1FF8DC2F1FF8DC2F1FF8DC2F1FF5096D7FF88BFEEFF8DC2F1FF8DC2
F1FF8DC2F1FF8DC2F1FF8DC2F1FF2C7BC7FF0000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
@ -300,11 +304,11 @@ inherited frmNewProject: TfrmNewProject
B2ED266CB1EDACD9FEFF5DA7E4FF0B6CCAFF0082F6FF127EE2FF0268CBFF2F8F
E5FFA6D6FCFF8EC3F0FF2775C4FF0057B2FF1669BCFF94C7F3FF90C3F2FF0856
A4F20053ABFA0058B3FF0055ACFA00356CC50000011900000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000004A91D4FFAFDBFFFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFF3783CCFFAFDBFFFFAFDBFFFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFF63A4DFFFA9D6FCFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFF3783CCFF0000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
@ -316,11 +320,11 @@ inherited frmNewProject: TfrmNewProject
E8FC9CCEF8FF217AD1FF0074E2FF0C74D6FF0287F9FF46A0EFFF3082CFFF2E89
D9FF97C9F5FFAFDBFFFFADD9FEFF4990D4FF045BB5FF0860B7FF60A1DEFFADD9
FDFF2068AEF100509FF10057B3FF0059B4FF004183DA00091353000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000004A91D4FFAFDBFFFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFF3783CCFFAFDBFFFFAFDBFFFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFF63A4DFFFA9D6FCFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFF3783CCFF0000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
@ -332,11 +336,11 @@ inherited frmNewProject: TfrmNewProject
FFFF82BDF1FF036FD5FF0086FEFF2984D9FF3586D1FFAEDAFEFF83C1F7FF178A
F2FF388CD7FF6BA8E1FFAFDBFFFFAFDBFFFF77B3E8FF196CBEFF0059B3FF2C7A
C8FFACD8FDFF5997CFF70250A0F10057B2FF0058B4FF004C99EB0020419A0000
0002000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0002000000000000000000000000000000004A91D4FFAFDBFFFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFF3783CCFFAFDBFFFFAFDBFFFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFF63A4DFFFA9D6FCFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFF3783CCFF0000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
@ -348,11 +352,11 @@ inherited frmNewProject: TfrmNewProject
9FDFA8D6FCFF3388D7FF3F92DCFFAFDBFFFF59A3E4FF2587DFFF0B6DCCFF61AB
EBFFAFDBFFFF56A2E3FF3F96E4FF9ECFF8FFAFDBFFFF9FD0F8FF3783CBFF0058
B2FF1165BAFF88BEEEFF97C9F5FF0A57A8F20052A7F70058B3FF0056AEFB0036
6DC60000021C0000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6DC60000021C0000000000000000000000001569BDFF3280CAFF3280CAFF3280
CAFF3280CAFF3280CAFF3280CAFF0F65BBFF3280CAFF3280CAFF3280CAFF3280
CAFF3280CAFF3280CAFF3280CAFF3280CAFF3280CAFF3280CAFF3280CAFF3280
CAFF3280CAFF3280CAFF3280CAFF3280CAFF1C6EC0FF307DC9FF3280CAFF3280
CAFF3280CAFF3280CAFF3280CAFF0F65BBFF0000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
@ -364,11 +368,11 @@ inherited frmNewProject: TfrmNewProject
021E154371C37EB0DEF760A2DDFF3C89D0FF0D83F0FF2591F2FF3682CDFF3082
D1FF5DA6E6FF0788FBFF2890F0FF3F8AD1FF79B5EAFFAFDBFFFFAFDBFFFF61A2
DEFF0B61B7FF065DB5FF5196D7FFAFDBFFFF286DB1F10050A0F10057B3FF0059
B4FF004184DB000A145700000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
B4FF004184DB000A145700000000000000004A91D4FFAFDBFFFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFF3783CCFFAFDBFFFFAFDBFFFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFF63A4DFFFA9D6FCFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFF3783CCFF0000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
@ -380,11 +384,11 @@ inherited frmNewProject: TfrmNewProject
000000000000061A2D7D3A71A5E1A5D3FBFF2277C9FF8AC0EFFF9FD1FBFF238B
E9FF1B7AD6FF1F7BD1FFAFDBFFFF9CCFFBFF2089E8FF5499D9FFA6D5FBFFAFDB
FFFF8EC2F0FF2676C4FF0059B2FF2272C2FFA5D3FAFF69A4DAFA0351A0F10057
B2FF0058B4FF004C9BEC0021439C000000030000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
B2FF0058B4FF004C9BEC0021439C000000034A91D4FFAFDBFFFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFF3783CCFFAFDBFFFFAFDBFFFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFF63A4DFFFA9D6FCFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFF3783CCFF0000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
@ -396,11 +400,11 @@ inherited frmNewProject: TfrmNewProject
0000000000000000000000010323174675C681B5E1F85C9EDAFF237ACFFF208B
EBFF7AB9F0FF3283CFFF3A8DDAFF1589EFFF2893F1FF65A9E3FF2578C8FF88C0
F1FFAFDBFFFFADD9FDFF4990D3FF025BB5FF0D63B8FF7AB5E9FF9ECFF7FF0E5A
A8F20051A4F50059B4FF0057B0FC00356BC50000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
A8F20051A4F50059B4FF0057B0FC00356BC54A91D4FFAFDBFFFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFF3783CCFFAFDBFFFFAFDBFFFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFF63A4DFFFA9D6FCFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFF3783CCFF0000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
@ -412,11 +416,11 @@ inherited frmNewProject: TfrmNewProject
000000000000000000000000000000000000071C32833D74A7E294C9F3FF408A
CEFF6FADE4FF3F9EF0FF0883F6FF2074C8FF8EC4F3FF99CDFAFF2D95F2FF1480
E2FF5398D7FFABD8FEFFAFDBFFFF79B4E9FF1769BEFF045BB5FF448DD2FFAFDB
FFFF3479BAF40050A2F2004791E6000C185F0000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
FFFF3479BAF40050A2F2004791E6000C185F1569BEFF3380CAFF3380CAFF3380
CAFF3380CAFF3380CAFF3380CAFF1065BBFF3380CAFF3380CAFF3380CAFF3380
CAFF3380CAFF3380CAFF3380CAFF3380CAFF3380CAFF3380CAFF3380CAFF3380
CAFF3380CAFF3380CAFF3380CAFF3380CAFF1D6FC1FF317ECAFF3380CAFF3380
CAFF3380CAFF3380CAFF3380CAFF1065BBFF0000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
@ -428,11 +432,11 @@ inherited frmNewProject: TfrmNewProject
000000000000000000000000000000000000000000000002042819497AC987B7
E5F970AEE7FF1372CFFF80BCF4FF94C9F5FF1D7ED6FF1977D1FF1083ECFF77B9
F2FF5FA5E1FF2E87D9FF90C4F2FFAFDBFFFF9FCEF8FF3782CBFF015AB4FF90C4
F2FFA1D1F9FF1D5A98E1000E1C66000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
F2FFA1D1F9FF1D5A98E1000E1C66000000004A91D4FFAFDBFFFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFF3783CCFFAFDBFFFFAFDBFFFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFF63A4DFFFA9D6FCFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFF3783CCFF0000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
@ -444,11 +448,11 @@ inherited frmNewProject: TfrmNewProject
0000000000000000000000000000000000000000000000000000000000010820
378A4179ABE480B8EAFF3F87CDFF3890E2FF0787F9FF3A8EDBFF3681CAFF88C0
F1FF3EA0F4FF148AF3FF3A87CFFF66A6DEFFA0D0F9FF4991D4FF468ED2FF568B
BCEA0E2E4FA20000000B00000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
BCEA0E2E4FA20000000B00000000000000004A91D4FFAFDBFFFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFF3783CCFFAFDBFFFFAFDBFFFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFF63A4DFFFA9D6FCFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFF3783CCFF0000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
@ -460,11 +464,11 @@ inherited frmNewProject: TfrmNewProject
0000000000000000000000000000000000000000000000000000000000000000
00000002052C1A4B7ECC8CBFEAFB3F8EDAFF4995D8FFAFDBFFFF5BA7EAFF1678
D3FF1375D0FF98CBF6FF96C9F5FF2474C3FF64A6E0FF7FB6E7FC1F507FCB0005
093B000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
093B000000000000000000000000000000004A91D4FFAFDBFFFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFF3783CCFFAFDBFFFFAFDBFFFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFF63A4DFFFA9D6FCFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFF3783CCFF0000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
@ -476,11 +480,11 @@ inherited frmNewProject: TfrmNewProject
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000209233C90467DB0E674B0E6FF2B7DCDFF1389EFFF62AD
ECFF3C85CDFF3782CAFF5599D9FFA5D3FBFF4077A9E209203789000000020000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000468ED3FFA6D4FBFFA6D4FBFFA6D4
FBFFA6D4FBFFA6D4FBFFA6D4FBFF3481CBFFA6D4FBFFA6D4FBFFA6D4FBFFA6D4
FBFFA6D4FBFFA6D4FBFFA6D4FBFFA6D4FBFFA6D4FBFFA6D4FBFFA6D4FBFFA6D4
FBFFA6D4FBFFA6D4FBFFA6D4FBFFA6D4FBFF5EA0DDFFA0D0F9FFA6D4FBFFA6D4
FBFFA6D4FBFFA6D4FBFFA6D4FBFF3481CBFF0000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
@ -492,11 +496,11 @@ inherited frmNewProject: TfrmNewProject
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000307321C4D80CD7CB4E6FC3482CBFF69A8
E0FF3E89CFFF90C4F2FF76ACD9F517436FC00001022100000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000002C7AC7FF67A7E1FF67A7E1FF67A7
E1FF67A7E1FF67A7E1FF67A7E1FF2172C2FF67A7E1FF67A7E1FF67A7E1FF67A7
E1FF67A7E1FF67A7E1FF67A7E1FF67A7E1FF67A7E1FF67A7E1FF67A7E1FF67A7
E1FF67A7E1FF67A7E1FF67A7E1FF67A7E1FF3B86CEFF64A4DFFF67A7E1FF67A7
E1FF67A7E1FF67A7E1FF67A7E1FF2172C2FF0000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
@ -508,11 +512,11 @@ inherited frmNewProject: TfrmNewProject
0000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000003092540944980B2E773AF
E5FFA2D2F9FF2E6397DA04122069000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000004A91D4FFAFDBFFFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFF3783CCFFAFDBFFFFAFDBFFFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFF63A4DFFFA9D6FCFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFF3783CCFF0000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
@ -524,11 +528,11 @@ inherited frmNewProject: TfrmNewProject
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000408381C4E
80CE103559AD0000001000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000004A91D4FFAFDBFFFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFF3783CCFFAFDBFFFFAFDBFFFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFF63A4DFFFA9D6FCFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFF3783CCFF0000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
@ -540,11 +544,11 @@ inherited frmNewProject: TfrmNewProject
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000004A91D4FFAFDBFFFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFF3783CCFFAFDBFFFFAFDBFFFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFF63A4DFFFA9D6FCFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFF3783CCFF0000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
@ -556,11 +560,11 @@ inherited frmNewProject: TfrmNewProject
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000001F71C2FF4991D4FF4991D4FF4991
D4FF4991D4FF4991D4FF4991D4FF176BBEFF4991D4FF4991D4FF4991D4FF4991
D4FF4991D4FF4991D4FF4991D4FF4991D4FF4991D4FF4991D4FF4991D4FF4991
D4FF4991D4FF4991D4FF4991D4FF4991D4FF2A78C6FF478FD3FF4991D4FF4991
D4FF4991D4FF4991D4FF4991D4FF176BBEFF0000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
@ -624,7 +628,7 @@ inherited frmNewProject: TfrmNewProject
Left = 18
Top = 292
Bitmap = {
494C010102000800280010001000FFFFFF002110FFFFFFFFFFFFFFFF424D3600
494C0101030008003C0010001000FFFFFF002110FFFFFFFFFFFFFFFF424D3600
0000000000003600000028000000400000001000000001002000000000000010
000000000000000000000000000000000000000000003F3F3F97C8C8C8FBC8C8
C8FBC8C8C8FBC8C8C8FBC8C8C8FBC8C8C8FBC8C8C8FBC8C8C8FBC8C8C8FBC8C8
@ -638,113 +642,113 @@ inherited frmNewProject: TfrmNewProject
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFC9C9C9FA00000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000176ABEFF3683CCFF3683CCFF3683
CCFF3683CCFF3683CCFF3683CCFF3683CCFF3683CCFF3683CCFF3683CCFF3683
CCFF1F70C2FF3683CCFF3683CCFF3683CCFF0000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000D0D0D0F1FFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFC9C9C9FA00000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000004A91D4FFAFDBFFFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDB
FFFF63A4DFFFAFDBFFFFAFDBFFFFAFDBFFFF0000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000CFCFCFF2FFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFC9C9C9FA00000000000000000000000000000000000000000000
00000000000F00284E98003771C80002062F0000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000003582CBFF7CB6EAFF7CB6EAFF7CB6
EAFF7CB6EAFF7CB6EAFF7CB6EAFF7CB6EAFF7CB6EAFF7CB6EAFF7CB6EAFF7CB6
EAFF478FD3FF7CB6EAFF7CB6EAFF7CB6EAFF0000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000CFCFCFF2FFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFC9C9C9FA0000000000000000000000000000000000000000000F
1D600059ABD90165C1E7044B90E3004893E70010206D00000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000004A91D4FFAFDBFFFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDB
FFFF63A4DFFFAFDBFFFFAFDBFFFFAFDBFFFF0000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000D3D3D3F4FFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFC9C9C9FA0000000000000000000000000002042700366BB10076
E1F6115A9FDB579BD9F9599BDBFE165594E00051A7F600274FAB000000130000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000003783CCFF82BAECFF82BAECFF82BA
ECFF82BAECFF82BAECFF82BAECFF82BAECFF82BAECFF82BAECFF82BAECFF82BA
ECFF4991D4FF82BAECFF82BAECFF82BAECFF0000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000D6D6D6F5FFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFC9C9C9FA0000000000000000001A357F0069CAEA055CAFE04180
BAE9398DDBFF0B84F0FF2A7CCDFF3583CAFF407AB2EA014993E7003D7CD50007
0F4B000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0F4B000000000000000000000000000000004A91D4FFAFDBFFFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDB
FFFF63A4DFFFAFDBFFFFAFDBFFFFAFDBFFFF0000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000D4D4D4F4FFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFC9C9C9FA0000000000000000023B72BA2064A3DD5CA7EAFF197C
D9FF2590F0FF368AD8FF9DCFF8FF5FA1DCFF1C6EC0FF5D9AD7FB0D4E8FDF0050
A3F4001B388F0000000300000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
A3F4001B388F0000000300000000000000004A91D4FFAFDBFFFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDB
FFFF63A4DFFFAFDBFFFFAFDBFFFFAFDBFFFF0000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000D4D4D4F4FFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFC9C9C9FA000000000000000000000011233C549E5DA3E0FA509E
E6FF4297E3FF3A94E5FF59A3E4FF74B3ECFF8EC2F1FF2876C3FF448ED2FF2D68
A2E4004D9CEE003367C20002052C000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
A2E4004D9CEE003367C20002052C000000004A91D4FFAFDBFFFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDB
FFFF63A4DFFFAFDBFFFFAFDBFFFFAFDBFFFF0000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000D4D4D4F4FFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFC9C9C9FA00000000000000000000000000000000050C124C4B77
A2D84E9CE1FF4098E7FF2984D9FF74B5EFFF4C9BE4FF9BCDF7FF549AD8FF2474
C3FF5491CAF5074B8EE1004893E700101F6D0000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
C3FF5491CAF5074B8EE1004893E700101F6D4A91D4FFAFDBFFFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDB
FFFF63A4DFFFAFDBFFFFAFDBFFFFAFDBFFFF0000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000D6D6D6F5FFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFC9C9C9FA00000000000000000000000000000000000000000000
00071B30438F64A1D9F856A2E9FF358DDEFF6DB1EDFF3092EBFF73B1E8FF87BE
EFFF2675C5FF60A0DDFF195896E1001D3A920000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
EFFF2675C5FF60A0DDFF195896E1001D3A924A91D4FFAFDBFFFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDB
FFFF63A4DFFFAFDBFFFFAFDBFFFFAFDBFFFF0000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000D6D6D6F5FFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFC9C9C9FA00000000000000000000000000000000000000000000
00000000000003070B3B436D93CF55A0E3FF449DE9FF519DE0FF40A1F2FF5498
D8FF77B3E8FF3F6E9CD8050B114A000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
D8FF77B3E8FF3F6E9CD8050B114A000000004A91D4FFAFDBFFFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDB
FFFF63A4DFFFAFDBFFFFAFDBFFFFAFDBFFFF0000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000D8D8D8F6FFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8E8E7FFE9E9
E9FFE9E9E9FFB5B5B4F500000000000000000000000000000000000000000000
00000000000000000000000000011425347E5497D4F7499BE4FF4C92D4FF6395
C3EB1422317A0000000200000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
C3EB1422317A0000000200000000000000002C7AC7FF67A7E1FF67A7E1FF67A7
E1FF67A7E1FF67A7E1FF67A7E1FF67A7E1FF67A7E1FF67A7E1FF67A7E1FF67A7
E1FF3B86CEFF67A7E1FF67A7E1FF67A7E1FF0000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000DADADAF7FFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8E8E8FFFFFF
FFFFC4C4C4E70E0E0E4700000000000000000000000000000000000000000000
0000000000000000000000000000000000000103052A375B7EC12A425BA20001
021F000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
021F000000000000000000000000000000004A91D4FFAFDBFFFFAFDBFFFFAFDB
FFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDBFFFFAFDB
FFFF63A4DFFFAFDBFFFFAFDBFFFFAFDBFFFF0000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000DBDBDBF8FFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9E9E9FFA0A0
A0D30505052C0000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000001F71C2FF4991D4FF4991D4FF4991
D4FF4991D4FF4991D4FF4991D4FF4991D4FF4991D4FF4991D4FF4991D4FF4991
D4FF2A78C6FF4991D4FF4991D4FF4991D4FF0000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000B3B3B3EBD0D0D0F1D4D4
D4F4D4D4D4F4D4D4D4F4D4D4D4F4D6D6D6F5DADADAF7DBDBDBF8747473C20101

View file

@ -79,8 +79,10 @@ implementation
uses
Keyman.Developer.System.HelpTopics,
Keyman.Developer.System.Project.Project,
Keyman.Developer.System.Project.ProjectFile,
Keyman.Developer.UI.Project.ProjectUI,
Keyman.Developer.UI.Project.UfrmNewProjectParameters,
Keyman.Developer.UI.Project.UfrmNewModelProjectParameters,
Keyman.Developer.UI.ImportWindowsKeyboardDialogManager,
dmActionsMain,
utilsystem;
@ -106,9 +108,16 @@ begin
Assert(False, 'Should not be able to have a project type of unknown here');
kptBasic:
Result := ShowNewProjectParameters(Owner);
kptWordlistLexicalModel:
Result := ShowNewModelProjectParameters(Owner);
kptBlankLexicalModel:
begin
modActionsMain.NewProject(ptLexicalModel);
Result := True;
end;
kptBlank:
begin
modActionsMain.OpenProject('');
modActionsMain.NewProject(ptKeyboard);
Result := True;
end;
kptImportWindowsKeyboard:
@ -147,6 +156,10 @@ begin
Result := kptBlank
else if lvItems.Selected.Caption = 'Import Windows Keyboard' then
Result := kptImportWindowsKeyboard
else if lvItems.Selected.Caption = 'Blank Lexical Model' then
Result := kptBlankLexicalModel
else if lvItems.Selected.Caption = 'Wordlist Lexical Model' then
Result := kptWordlistLexicalModel
else
Result := kptUnknown;
end;

View file

@ -1,7 +1,7 @@
inherited frmNewProjectParameters: TfrmNewProjectParameters
BorderIcons = [biSystemMenu]
BorderStyle = bsDialog
Caption = 'New Project'
Caption = 'New Basic Keyboard Project'
ClientHeight = 309
ClientWidth = 625
Position = poScreenCenter
@ -215,7 +215,7 @@ inherited frmNewProjectParameters: TfrmNewProjectParameters
Filter = 'Project files (*.kpj)|*.kpj|All files (*.*)|*.*'
FilterIndex = 0
Title = 'Create New Project'
Left = 188
Top = 152
Left = 396
Top = 240
end
end

View file

@ -20,7 +20,8 @@ uses
kpsfile,
PackageInfo,
UfrmTike,
UKeymanTargets;
UKeymanTargets,
utilfiletypes;
type
TfrmNewProjectParameters = class(TTikeForm)
@ -64,8 +65,8 @@ type
procedure editFileNameChange(Sender: TObject);
procedure cmdBrowseClick(Sender: TObject);
private
pack: TKPSFile;
FSetup: Integer; // Used temporarily for storing language list
pack: TKPSFile; // Used temporarily for storing language list
FSetup: Integer;
function GetAuthor: string;
function GetBasePath: string;
function GetCopyright: string;
@ -85,13 +86,14 @@ type
protected
function GetHelpTopic: string; override;
public
property KeyboardName: string read GetKeyboardName write SetKeyboardName;
property Copyright: string read GetCopyright;
property Version: string read GetVersion;
property Author: string read GetAuthor;
property Targets: TKeymanTargets read GetTargets;
property BCP47Tags: string read GetBCP47Tags write SetBCP47Tags;
property BasePath: string read GetBasePath;
property KeyboardName: string read GetKeyboardName write SetKeyboardName;
property KeyboardID: string read GetKeyboardID write SetKeyboardID;
end;
@ -111,6 +113,7 @@ uses
Keyman.Developer.System.Project.Project,
Keyman.Developer.System.Project.ProjectFile,
Keyman.Developer.System.KeyboardProjectTemplate,
Keyman.Developer.System.ProjectTemplate,
Keyman.Developer.UI.UfrmSelectBCP47Language,
Keyman.System.KeyboardUtils;
@ -128,7 +131,7 @@ uses
function ShowNewProjectParameters(Owner: TComponent): Boolean;
var
f: TfrmNewProjectParameters;
kpt: TKeyboardProjectTemplate;
pt: TProjectTemplate;
begin
f := TfrmNewProjectParameters.Create(Owner);
try
@ -136,16 +139,16 @@ begin
if not Result then
Exit;
kpt := TKeyboardProjectTemplate.Create(f.BasePath, f.KeyboardID, f.Targets);
pt := TKeyboardProjectTemplate.Create(f.BasePath, f.KeyboardID, f.Targets);
try
kpt.Name := f.KeyboardName;
kpt.Copyright := f.Copyright;
kpt.Author := f.Author;
kpt.Version := f.Version;
kpt.BCP47Tags := f.BCP47Tags;
pt.Name := f.KeyboardName;
pt.Copyright := f.Copyright;
pt.Author := f.Author;
pt.Version := f.Version;
pt.BCP47Tags := f.BCP47Tags;
try
kpt.Generate;
pt.Generate;
except
on E:EFOpenError do
begin
@ -154,11 +157,11 @@ begin
end;
end;
modActionsMain.OpenProject(kpt.ProjectFilename);
modActionsMain.OpenProject(pt.ProjectFilename);
Result := True;
finally
kpt.Free;
pt.Free;
end;
finally
f.Free;
@ -338,6 +341,7 @@ begin
(Trim(editPath.Text) <> '') and
TKeyboardUtils.IsValidKeyboardID(Trim(editFileName.Text), True) and
(GetTargets <> []);
cmdOK.Enabled := e;
e := gridKeyboardLanguages.RowCount > 1;

View file

@ -58,14 +58,14 @@
<xsl:with-param name="caption">Build all</xsl:with-param>
<xsl:with-param name="command">keyman:compileall</xsl:with-param>
<xsl:with-param name="enabled">
<xsl:if test="not(KeymanDeveloperProject/Files/File[(FileType='.kps' or FileType='.kmn') and not (ParentFileID)])">false</xsl:if>
<xsl:if test="not(KeymanDeveloperProject/Files/File[(FileType='.kps' or FileType='.kmn' or FileType='.ts') and not (ParentFileID)])">false</xsl:if>
</xsl:with-param>
</xsl:call-template>
<xsl:call-template name="button">
<xsl:with-param name="caption">Clean all</xsl:with-param>
<xsl:with-param name="command">keyman:cleanall</xsl:with-param>
<xsl:with-param name="enabled">
<xsl:if test="not(KeymanDeveloperProject/Files/File[(FileType='.kps' or FileType='.kmn') and not (ParentFileID)])">false</xsl:if>
<xsl:if test="not(KeymanDeveloperProject/Files/File[(FileType='.kps' or FileType='.kmn' or FileType='.ts') and not (ParentFileID)])">false</xsl:if>
</xsl:with-param>
<xsl:with-param name="width">auto</xsl:with-param>
</xsl:call-template>
@ -74,7 +74,7 @@
<br />
<div>
<xsl:for-each select="/KeymanDeveloperProject/Files/File[FileType!='.kps' and FileType!='.kmn' and not(ParentFileID)]">
<xsl:for-each select="/KeymanDeveloperProject/Files/File[FileType!='.kps' and FileType!='.kmn' and FileType!='.ts' and not(ParentFileID)]">
<xsl:variable name="FileState" select="/KeymanDeveloperProject/FileStates/FileState[ID=current()/ID]" />
<xsl:call-template name="file">
<xsl:with-param name="file_description"></xsl:with-param>
@ -86,7 +86,7 @@
</div>
</xsl:template>
<xsl:template mode="options_menu" match="/KeymanDeveloperProject/Files/File[FileType!='.kps' and FileType!='.kmn']" >
<xsl:template mode="options_menu" match="/KeymanDeveloperProject/Files/File[FileType!='.kps' and FileType!='.kmn' and FileType!='.ts']" >
<div class="menu">
<xsl:attribute name="id">menu_options_<xsl:value-of select="ID"/></xsl:attribute>
<xsl:call-template name="menuitem">
@ -97,12 +97,10 @@
<xsl:with-param name="caption">Build</xsl:with-param>
<xsl:with-param name="command">keyman:compilefile?id=<xsl:value-of select="ID" /></xsl:with-param>
</xsl:call-template>
<xsl:if test="/KeymanDeveloperProject/Modules/Module[ID='BrandingPack']">
<xsl:call-template name="menuitem">
<xsl:with-param name="caption">Build installer</xsl:with-param>
<xsl:with-param name="command">keyman:package_compileinstaller?id=<xsl:value-of select="ID" /></xsl:with-param>
</xsl:call-template>
</xsl:if>
<xsl:call-template name="menuitem">
<xsl:with-param name="caption">Build installer</xsl:with-param>
<xsl:with-param name="command">keyman:package_compileinstaller?id=<xsl:value-of select="ID" /></xsl:with-param>
</xsl:call-template>
<xsl:call-template name="menuitem">
<xsl:with-param name="caption">Clean</xsl:with-param>
<xsl:with-param name="command">keyman:cleanfile?id=<xsl:value-of select="ID" /></xsl:with-param>

View file

@ -14,10 +14,7 @@
<ul>
<li>
<a href="help:guides/develop/tutorial">Model Tutorial</a>
</li>
<li>
<a href="help:language/">Keyman Model Reference</a>
<a href="help:guides/lexical-models/intro">Model Tutorial</a>
</li>
</ul>
</div>
@ -26,7 +23,21 @@
<h2>Creating your first lexical model</h2>
<p>
Click the New Model button to create a model for any device. This will open the Model Editor.
Click the New Model button to create a lexical model for predictive text. Lexical model source files are TypeScript files.
In version 12, the model format supported is "trie-1.0". The model source file will include references to wordlist source
files of .tsv format, which can be edited in a compatible spreadsheet program or generated from a number of other tools;
check the <a href='help:guides/lexical-models/intro'>online documentation</a> for more details.
</p>
<p>
Lexical model filenames should have the format <b><i>author</i>.<i>bcp47</i>.<i>uniq</i>.model.ts</b>. A compiled lexical
model file is a JavaScript file.
</p>
<p>
A corresponding package file will be needed (with extension <b>.model.kps</b>) in order to deploy the model to mobile
devices. This can be created in the <b>Packages</b> tab. Note that a package file can contain either model file(s) or
keyboard file(s), not both.
</p>
<table class="io">

View file

@ -64,7 +64,17 @@ body.tab-3 .page#page-3,
body.tab-4 .page#page-4 {
display: block;
}
html.type-lexical-model .tabb#tabb1 {
/* Hide keyboards tab for lexical model projects */
display: none;
}
html.type-keyboard .tabb#tabb2 {
/* Hide lexical-models tab for keyboard projects */
display: none;
}
.help-container {
display: none;

View file

@ -106,15 +106,26 @@ function showhideupper()
}
savestate();
}
function isTabVisible(n) {
return document.getElementById('tabb'+n).offsetParent != null;
}
document.onkeydown = function()
{
switch(event.keyCode)
{
case 33: //pgup
if(tabselected > 0) selecttabb(tabselected-1);
if(tabselected > 0) {
do {
selecttabb(tabselected-1);
} while(!isTabVisible(tabselected) && tabselected > 0);
}
break;
case 34: //pgdn
if(tabselected < 3) selecttabb(tabselected+1);
if(tabselected < 4) {
do {
selecttabb(tabselected+1);
} while(!isTabVisible(tabselected) && tabselected < 4)
}
break;
default:
event.returnValue = true;

View file

@ -11,6 +11,15 @@
<xsl:template match="/">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:k="http://www.tavultesoft.com/xml/70">
<xsl:variable name="lowercase" select="'abcdefghijklmnopqrstuvwxyz'" />
<xsl:variable name="uppercase" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'" />
<xsl:attribute name='class'>
<xsl:choose>
<xsl:when test="translate(/KeymanDeveloperProject/Options/ProjectType, $uppercase, $lowercase) = 'lexicalmodel'">type-lexical-model</xsl:when>
<xsl:otherwise>type-keyboard</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<xsl:call-template name="head" />
<body onload="pageload()">
<div id="state"><xsl:copy-of select="/KeymanDeveloperProject/ViewState" /></div>

View file

@ -66,7 +66,7 @@ var
begin
Result := False;
Found := False;
with TProjectConsole.Create(AProjectFilename, False) do
with TProjectConsole.Create(ptUnknown, AProjectFilename, False) do
try
Options.CheckFilenameConventions := Options.CheckFilenameConventions or ACheckFilenameConventions; // never downgrade this option
FullySilent := AFullySilent;

View file

@ -6,31 +6,24 @@ uses
System.SysUtils,
kpsfile,
UKeymanTargets;
Keyman.Developer.System.ProjectTemplate,
UKeymanTargets,
utilfiletypes;
type
EKeyboardProjectTemplate = class(Exception);
EKeyboardProjectTemplate = class(EProjectTemplate);
TKeyboardProjectTemplate = class
TKeyboardProjectTemplate = class(TProjectTemplate)
private
FName: string;
FBasePath: string;
FKeyboardID: string;
FTargets: TKeymanTargets;
FIconFilename: string;
FOSKFilename: string;
FTouchLayoutFilename: string;
FAuthor: string;
FCopyright: string;
FVersion: string;
FBCP47Tags: string;
FIncludeIcon: Boolean;
function GetFilename(Base: string): string;
function GetIconFilename: string;
function GetKeyboardFilename: string;
function GetOSKFilename: string;
function GetPackageFilename: string;
function GetProjectFilename: string;
function GetTouchLayoutFilename: string;
function HasIcon: Boolean;
@ -40,29 +33,23 @@ type
procedure WriteKMN;
procedure WriteKPS;
procedure WriteKPJ;
procedure WriteKVKS;
procedure WriteTouchLayout;
procedure WriteKPJ;
procedure WriteRepositoryMetadata;
procedure WriteDocumentation;
procedure WriteKeyboardInfo;
procedure Transform(const SourceFile: string; DestFile: string = '');
function DataPath: string;
procedure SetKeyboardLanguages(kps: TkpsFile);
protected
const
SFileTemplate_KeyboardInfo = '%s.keyboard_info'; // in root
SDataPath_BasicKeyboard = 'basic-keyboard\';
function DataPath: string; override;
public
constructor Create(const BasePath, KeyboardID: string; Targets: TKeymanTargets);
destructor Destroy; override;
procedure Generate;
property Name: string read FName write FName;
property Copyright: string read FCopyright write FCopyright;
property Author: string read FAuthor write FAuthor;
property Version: string read FVersion write FVersion;
property BCP47Tags: string read FBCP47Tags write FBCP47Tags;
procedure Generate; override;
property IncludeIcon: Boolean read FIncludeIcon write FIncludeIcon;
property KeyboardFilename: string read GetKeyboardFilename;
property ProjectFilename: string read GetProjectFilename;
property PackageFilename: string read GetPackageFilename;
property OSKFilename: string read GetOSKFilename;
property IconFilename: string read GetIconFilename;
property TouchLayoutFilename: string read GetTouchLayoutFilename;
@ -86,43 +73,22 @@ uses
PackageInfo,
RedistFiles,
TouchLayout,
utilfiletypes,
utilstr,
VisualKeyboard;
const
SFolder_Source = 'source';
SFolder_Build = 'build';
SFile_ReadmeMD = 'README.md'; // in root
SFile_HistoryMD = 'HISTORY.md'; // in root
SFile_LicenseMD = 'LICENSE.md'; // in root
SFile_WelcomeHTM = 'welcome.htm'; // in source/
SFile_ReadmeHTM = 'readme.htm'; // in source/
SFileTemplate_KeyboardInfo = '%s.keyboard_info'; // in root
{ TKeyboardProjectTemplate }
constructor TKeyboardProjectTemplate.Create(const BasePath, KeyboardID: string; Targets: TKeymanTargets);
begin
inherited Create;
FBasePath := IncludeTrailingPathDelimiter(ExpandFileName(BasePath));
FKeyboardID := LowerCase(KeyboardID);
inherited Create(BasePath, KeyboardID);
FTargets := Targets;
FVersion := '1.0';
end;
destructor TKeyboardProjectTemplate.Destroy;
begin
inherited Destroy;
end;
procedure TKeyboardProjectTemplate.Generate;
begin
if not ForceDirectories(FBasePath + FKeyboardID + '\' + SFolder_Source) then
raise EKeyboardProjectTemplate.Create('Could not create destination path '+FBasePath+FKeyboardID);
if not ForceDirectories(BasePath + ID + '\' + SFolder_Source) then
raise EKeyboardProjectTemplate.Create('Could not create destination path '+BasePath+ID);
WriteDocumentation;
@ -140,16 +106,6 @@ begin
WriteKeyboardInfo;
end;
function TKeyboardProjectTemplate.GetFilename(Base: string): string;
begin
if Base = '' then
Result := ''
else if ExtractFileExt(Base) = Base then
Result := FBasePath + FKeyboardID + '\' + SFolder_Source + '\' + FKeyboardID + Base
else
Result := FBasePath + FKeyboardID + '\' + SFolder_Source + '\' + Base;
end;
function TKeyboardProjectTemplate.GetIconFilename: string;
begin
if FIncludeIcon
@ -167,17 +123,6 @@ begin
Result := GetFilename(FOSKFilename);
end;
function TKeyboardProjectTemplate.GetPackageFilename: string;
begin
Result := GetFilename(Ext_PackageSource);
end;
function TKeyboardProjectTemplate.GetProjectFilename: string;
begin
// Project file goes in parent folder
Result := FBasePath + FKeyboardID + '\' + FKeyboardID + Ext_ProjectSource;
end;
function TKeyboardProjectTemplate.GetTouchLayoutFilename: string;
begin
Result := GetFilename(FTouchLayoutFilename);
@ -203,19 +148,12 @@ begin
Result := (TouchKeymanTargets+[ktAny]) * FTargets <> [];
end;
procedure TKeyboardProjectTemplate.WriteDocumentation;
begin
// Write readme.htm and welcome.htm
Transform(SFolder_Source + '\' + SFile_WelcomeHTM);
Transform(SFolder_Source + '\' + SFile_ReadmeHTM);
end;
procedure TKeyboardProjectTemplate.WriteKeyboardInfo;
begin
// Write keyboardid.keyboard_info
Transform(
Format(SFileTemplate_KeyboardInfo, ['keyboard']),
Format(SFileTemplate_KeyboardInfo, [FKeyboardID])
Format(SFileTemplate_KeyboardInfo, [ID])
);
end;
@ -230,13 +168,13 @@ begin
kp.FileName := KeyboardFilename;
kp.InitialComment := #13#10+
FKeyboardID+' generated from template at '+FormatDateTime('yyyy-mm-dd hh:nn:ss', Now)+#13#10+
'with name "'+FName+'"'#13#10;
kp.SetSystemStoreValue(ssName, FName);
if FCopyright <> '' then
kp.SetSystemStoreValue(ssCopyright, FCopyright);
ID+' generated from template at '+FormatDateTime('yyyy-mm-dd hh:nn:ss', Now)+#13#10+
'with name "'+Name+'"'#13#10;
kp.SetSystemStoreValue(ssName, Name);
if Copyright <> '' then
kp.SetSystemStoreValue(ssCopyright, Copyright);
kp.SetSystemStoreValue(ssVersion, SKeymanKeyboardVersion);
kp.SetSystemStoreValue(ssKeyboardVersion, FVersion);
kp.SetSystemStoreValue(ssKeyboardVersion, Version);
kp.SetSystemStoreValue(ssTargets, KeymanTargetsToString(FTargets));
if HasIcon then
@ -272,7 +210,7 @@ procedure TKeyboardProjectTemplate.WriteKPJ;
var
kpj: TProject;
begin
kpj := TProject.Create(GetProjectFilename);
kpj := TProject.Create(ptKeyboard, GetProjectFilename);
try
kpj.Options.BuildPath := '$PROJECTPATH\' + SFolder_Build;
kpj.Options.WarnDeprecatedCode := True;
@ -284,10 +222,10 @@ begin
kpj.Files.Add(TkpsProjectFile.Create(kpj, GetPackageFilename, nil));
// Add metadata files to project
kpj.Files.Add(TOpenableProjectFile.Create(kpj, FBasePath + FKeyboardID + '\' + SFile_HistoryMD, nil));
kpj.Files.Add(TOpenableProjectFile.Create(kpj, FBasePath + FKeyboardID + '\' + SFile_LicenseMD, nil));
kpj.Files.Add(TOpenableProjectFile.Create(kpj, FBasePath + FKeyboardID + '\' + SFile_ReadmeMD, nil));
kpj.Files.Add(TOpenableProjectFile.Create(kpj, FBasePath + FKeyboardID + '\' + Format(SFileTemplate_KeyboardInfo, [FKeyboardID]), nil));
kpj.Files.Add(TOpenableProjectFile.Create(kpj, BasePath + ID + '\' + SFile_HistoryMD, nil));
kpj.Files.Add(TOpenableProjectFile.Create(kpj, BasePath + ID + '\' + SFile_LicenseMD, nil));
kpj.Files.Add(TOpenableProjectFile.Create(kpj, BasePath + ID + '\' + SFile_ReadmeMD, nil));
kpj.Files.Add(TOpenableProjectFile.Create(kpj, BasePath + ID + '\' + Format(SFileTemplate_KeyboardInfo, [ID]), nil));
kpj.Save;
finally
@ -304,9 +242,9 @@ begin
kps := TKPSFile.Create;
try
// Set kps metadata
kps.Info.Desc[PackageInfo_Name] := FName;
kps.Info.Desc[PackageInfo_Copyright] := FCopyright;
kps.Info.Desc[PackageInfo_Author] := FAuthor;
kps.Info.Desc[PackageInfo_Name] := Name;
kps.Info.Desc[PackageInfo_Copyright] := Copyright;
kps.Info.Desc[PackageInfo_Author] := Author;
kps.KPSOptions.FollowKeyboardVersion := True;
kps.FileName := GetPackageFilename;
@ -314,7 +252,7 @@ begin
if HasKMX then
begin
f := TPackageContentFile.Create(kps);
f.FileName := FBasePath + FKeyboardID + '\' + SFolder_Build + '\' + FKeyboardID + Ext_KeymanFile;
f.FileName := BasePath + ID + '\' + SFolder_Build + '\' + ID + Ext_KeymanFile;
kps.Files.Add(f);
end;
@ -322,7 +260,7 @@ begin
if HasTouchLayout then
begin
f := TPackageContentFile.Create(kps);
f.FileName := FBasePath + FKeyboardID + '\' + SFolder_Build + '\' + FKeyboardID + Ext_Javascript;
f.FileName := BasePath + ID + '\' + SFolder_Build + '\' + ID + Ext_Javascript;
kps.Files.Add(f);
end;
@ -330,29 +268,29 @@ begin
if HasKVKS then
begin
f := TPackageContentFile.Create(kps);
f.FileName := FBasePath + FKeyboardID + '\' + SFolder_Build + '\' + FKeyboardID + Ext_VisualKeyboard;
f.FileName := BasePath + ID + '\' + SFolder_Build + '\' + ID + Ext_VisualKeyboard;
kps.Files.Add(f);
end;
// Add welcome
f := TPackageContentFile.Create(kps);
f.FileName := FBasePath + FKeyboardID + '\' + SFolder_Source + '\' + SFile_WelcomeHTM;
f.FileName := BasePath + ID + '\' + SFolder_Source + '\' + SFile_WelcomeHTM;
kps.Files.Add(f);
// Add readme
f := TPackageContentFile.Create(kps);
f.FileName := FBasePath + FKeyboardID + '\' + SFolder_Source + '\' + SFile_ReadmeHTM;
f.FileName := BasePath + ID + '\' + SFolder_Source + '\' + SFile_ReadmeHTM;
kps.Files.Add(f);
kps.Options.ReadmeFile := f;
// Add metadata about the keyboard
pk := TPackageKeyboard.Create(kps);
pk.Name := FName;
pk.ID := FKeyboardID;
pk.Version := FVersion;
pk.Name := Name;
pk.ID := ID;
pk.Version := Version;
kps.Keyboards.Add(pk);
SetKeyboardLanguages(kps);
SetPackageLanguageMetadata(kps, pk.Languages);
kps.SaveXML;
finally
@ -360,43 +298,6 @@ begin
end;
end;
procedure TKeyboardProjectTemplate.SetKeyboardLanguages(kps: TkpsFile);
var
tag, tags, s: string;
bcp47tag: TBCP47Tag;
pkl: TPackageKeyboardLanguage;
begin
tags := Trim(FBCP47Tags);
tag := StrToken(tags, ' ');
while tag <> '' do
begin
pkl := TPackageKeyboardLanguage.Create(kps);
bcp47tag := TBCP47Tag.Create(tag);
try
bcp47tag.Canonicalize;
pkl.ID := bcp47tag.Tag;
if not TLanguageCodeUtils.BCP47Languages.TryGetValue(bcp47tag.Language, pkl.Name) then
begin
pkl.Name := bcp47tag.Language;
end;
if bcp47tag.Script <> '' then
begin
if TLanguageCodeUtils.BCP47Languages.TryGetValue(bcp47tag.Script, s) then
pkl.Name := pkl.Name + ' ('+s+')';
end;
finally
bcp47tag.Free;
end;
kps.Keyboards[0].Languages.Add(pkl);
tag := StrToken(tags, ' ');
end;
end;
procedure TKeyboardProjectTemplate.WriteKVKS;
var
vk: TVisualKeyboard;
@ -404,20 +305,13 @@ begin
Assert(HasKVKS);
vk := TVisualKeyboard.Create;
try
vk.Header.AssociatedKeyboard := FKeyboardID;
vk.Header.AssociatedKeyboard := ID;
vk.SaveToFile(OSKFilename, kvksfXML);
finally
vk.Free;
end;
end;
procedure TKeyboardProjectTemplate.WriteRepositoryMetadata;
begin
Transform(SFile_HistoryMD);
Transform(SFile_LicenseMD);
Transform(SFile_ReadmeMD);
end;
procedure TKeyboardProjectTemplate.WriteTouchLayout;
var
tl: TTouchLayout;
@ -457,80 +351,7 @@ end;
function TKeyboardProjectTemplate.DataPath: string;
begin
Result := GetRedistProjectTemplatePath;
end;
procedure TKeyboardProjectTemplate.Transform(const SourceFile: string; DestFile: string = '');
var
s: string;
ss: TStringStream;
function GetLanguageTagListForKeyboardInfo: string;
var
tags, tag: string;
bcp47tag: TBCP47Tag;
begin
// We won't worry about line breaks...
tags := Trim(FBCP47Tags);
tag := StrToken(tags, ' ');
Result := '';
while tag <> '' do
begin
if Result <> '' then
Result := Result + ', ';
bcp47tag := TBCP47Tag.Create(tag);
try
bcp47tag.Canonicalize;
Result := Result + '"' + bcp47tag.Tag + '"';
finally
bcp47tag.Free;
end;
tag := StrToken(tags, ' ');
end;
end;
function GetPlatformsDotListForReadme: string;
var
kt: TKeymanTarget;
begin
Result := '';
for kt := Low(TKeymanTarget) to High(TKeymanTarget) do
begin
if kt = ktAny then
Continue;
Result := Result + ' * ' + SKeymanTargetNames[kt] + #13#10;
end;
end;
begin
if DestFile = '' then
DestFile := SourceFile;
ss := TStringStream.Create('', TEncoding.UTF8);
try
ss.LoadFromFile(DataPath + SourceFile);
s := ss.DataString;
finally
ss.Free;
end;
s := ReplaceStr(s, '$NAME', FName);
s := ReplaceStr(s, '$VERSION', FVersion);
s := ReplaceStr(s, '$COPYRIGHT', FCopyright);
s := ReplaceStr(s, '$AUTHOR', FAuthor);
s := ReplaceStr(s, '$DATE', FormatDateTime('yyyy-mm-dd', Now));
if Pos('$LANGUAGES_KEYBOARD_INFO', s) > 0 then
s := ReplaceStr(s, '$LANGUAGES_KEYBOARD_INFO', GetLanguageTagListForKeyboardInfo);
if Pos('$PLATFORMS_DOTLIST_README', s) > 0 then
s := ReplaceStr(s, '$PLATFORMS_DOTLIST_README', GetPlatformsDotListForReadme);
ss := TStringStream.Create(s, TEncoding.UTF8);
try
ss.SaveToFile(FBasePath + FKeyboardID + '\' + DestFile);
finally
ss.Free;
end;
Result := inherited DataPath + SDataPath_BasicKeyboard;
end;
end.

View file

@ -0,0 +1,203 @@
unit Keyman.Developer.System.ModelProjectTemplate;
interface
uses
System.SysUtils,
Keyman.Developer.System.ProjectTemplate,
kpsfile,
UKeymanTargets,
utilfiletypes;
type
EModelProjectTemplate = class(Exception);
TModelProjectTemplate = class(TProjectTemplate)
private
procedure WriteModel;
procedure WriteWordlist;
procedure WriteKPS;
procedure WriteKPJ;
procedure WriteModelInfo;
function GetModelFilename: string;
function GetWordlistFilename: string;
protected
const
SFileTemplate_ModelInfo = '%s.model_info'; // in root
SFileTemplate_Package = '%s.model.kps';
SFilename_Model = 'model.ts'; // Only for source
SFilename_Wordlist = 'wordlist.tsv';
SFileTemplate_Model = '%s.model.ts';
SFileTemplate_CompiledModel = '%s.model.js';
SDataPath_WordlistLexicalModel = 'wordlist-lexical-model\';
function DataPath: string; override;
function GetPackageFilename: string; override;
public
constructor Create(const BasePath, ModelID: string);
procedure Generate; override;
property ModelFilename: string read GetModelFilename;
property WordlistFilename: string read GetWordlistFilename;
end;
implementation
uses
System.Classes,
System.StrUtils,
BCP47Tag,
Keyman.System.LanguageCodeUtils,
KeymanVersion,
Keyman.Developer.System.Project.modelTsProjectFile,
Keyman.Developer.System.Project.kpsProjectFile,
Keyman.Developer.System.Project.ProjectFile,
Keyman.Developer.System.Project.ProjectFiles,
PackageInfo,
RedistFiles,
TouchLayout,
utilstr,
VisualKeyboard;
{ TModelProjectTemplate }
constructor TModelProjectTemplate.Create(const BasePath, ModelID: string);
begin
inherited Create(BasePath, ModelID);
end;
procedure TModelProjectTemplate.Generate;
begin
if not ForceDirectories(BasePath + ID + '\' + SFolder_Source) then
raise EModelProjectTemplate.Create('Could not create destination path '+BasePath+ID);
WriteDocumentation;
WriteModel;
WriteWordlist;
WriteKPS;
WriteKPJ;
WriteRepositoryMetadata;
WriteModelInfo;
end;
function TModelProjectTemplate.GetModelFilename: string;
begin
Result := GetFilename(Format(SFileTemplate_Model, [ID]));
end;
function TModelProjectTemplate.GetWordlistFilename: string;
begin
Result := GetFilename(SFilename_Wordlist);
end;
function TModelProjectTemplate.GetPackageFilename: string;
begin
Result := GetFilename(Format(SFileTemplate_Package, [ID]));
end;
procedure TModelProjectTemplate.WriteModel;
begin
Transform(SFolder_Source + '\' + SFilename_Model,
Format(SFolder_Source + '\' + SFileTemplate_Model, [ID]));
end;
procedure TModelProjectTemplate.WriteModelInfo;
begin
// Write modelid.model_info
Transform(
Format(SFileTemplate_ModelInfo, ['model']),
Format(SFileTemplate_ModelInfo, [ID])
);
end;
procedure TModelProjectTemplate.WriteWordlist;
begin
Transform(SFolder_Source + '\' + SFilename_Wordlist);
end;
procedure TModelProjectTemplate.WriteKPJ;
var
kpj: TProject;
begin
kpj := TProject.Create(ptLexicalModel, GetProjectFilename);
try
kpj.Options.BuildPath := '$PROJECTPATH\' + SFolder_Build;
kpj.Options.WarnDeprecatedCode := True;
kpj.Options.CompilerWarningsAsErrors := True;
kpj.Options.CheckFilenameConventions := True;
// Add keyboard and package to project
kpj.Files.Add(TmodelTsProjectFile.Create(kpj, GetModelFilename, nil));
kpj.Files.Add(TkpsProjectFile.Create(kpj, GetPackageFilename, nil));
// Add metadata files to project
kpj.Files.Add(TOpenableProjectFile.Create(kpj, BasePath + ID + '\' + SFile_HistoryMD, nil));
kpj.Files.Add(TOpenableProjectFile.Create(kpj, BasePath + ID + '\' + SFile_LicenseMD, nil));
kpj.Files.Add(TOpenableProjectFile.Create(kpj, BasePath + ID + '\' + SFile_ReadmeMD, nil));
kpj.Files.Add(TOpenableProjectFile.Create(kpj, BasePath + ID + '\' + Format(SFileTemplate_ModelInfo, [ID]), nil));
kpj.Save;
finally
kpj.Free;
end;
end;
procedure TModelProjectTemplate.WriteKPS;
var
kps: TKPSFile;
f: TPackageContentFile;
plm: TPackageLexicalModel;
begin
kps := TKPSFile.Create;
try
// Set kps metadata
kps.Info.Desc[PackageInfo_Name] := Name;
kps.Info.Desc[PackageInfo_Copyright] := Copyright;
kps.Info.Desc[PackageInfo_Author] := Author;
kps.KPSOptions.FollowKeyboardVersion := True;
kps.FileName := GetPackageFilename;
// Add model.js
f := TPackageContentFile.Create(kps);
f.FileName := BasePath + ID + '\' + SFolder_Build + '\' + Format(SFileTemplate_CompiledModel, [ID]);
kps.Files.Add(f);
// Add welcome
f := TPackageContentFile.Create(kps);
f.FileName := BasePath + ID + '\' + SFolder_Source + '\' + SFile_WelcomeHTM;
kps.Files.Add(f);
// Add readme
f := TPackageContentFile.Create(kps);
f.FileName := BasePath + ID + '\' + SFolder_Source + '\' + SFile_ReadmeHTM;
kps.Files.Add(f);
kps.Options.ReadmeFile := f;
// Add metadata about the keyboard
plm := TPackageLexicalModel.Create(kps);
plm.Name := Name;
plm.ID := ID;
plm.Version := Version;
kps.LexicalModels.Add(plm);
SetPackageLanguageMetadata(kps, plm.Languages);
kps.SaveXML;
finally
kps.Free;
end;
end;
function TModelProjectTemplate.DataPath: string;
begin
Result := inherited DataPath + SDataPath_WordlistLexicalModel;
end;
end.

View file

@ -0,0 +1,247 @@
unit Keyman.Developer.System.ProjectTemplate;
interface
uses
System.SysUtils,
kpsfile,
PackageInfo,
UKeymanTargets,
utilfiletypes;
type
EProjectTemplate = class(Exception);
TProjectTemplate = class
private
FID: string;
FName: string;
FBasePath: string;
FAuthor: string;
FCopyright: string;
FVersion: string;
FBCP47Tags: string;
FProjectType: TKeymanProjectType;
protected
const
SFolder_Source = 'source';
SFolder_Build = 'build';
SFile_ReadmeMD = 'README.md'; // in root
SFile_HistoryMD = 'HISTORY.md'; // in root
SFile_LicenseMD = 'LICENSE.md'; // in root
SFile_WelcomeHTM = 'welcome.htm'; // in source/
SFile_ReadmeHTM = 'readme.htm'; // in source/
function GetFilename(Base: string): string;
function DataPath: string; virtual;
function GetPackageFilename: string; virtual;
function GetProjectFilename: string; virtual;
procedure WriteRepositoryMetadata;
procedure WriteDocumentation;
procedure Transform(const SourceFile: string; DestFile: string = '');
procedure SetPackageLanguageMetadata(kps: TKpsFile; languages: TPackageKeyboardLanguageList);
property BasePath: string read FBasePath;
property ID: string read FID;
public
constructor Create(const BasePath, ID: string);
procedure Generate; virtual; abstract;
property ProjectType: TKeymanProjectType read FProjectType;
property Name: string read FName write FName;
property Copyright: string read FCopyright write FCopyright;
property Author: string read FAuthor write FAuthor;
property Version: string read FVersion write FVersion;
property BCP47Tags: string read FBCP47Tags write FBCP47Tags;
property ProjectFilename: string read GetProjectFilename;
property PackageFilename: string read GetPackageFilename;
end;
implementation
uses
System.Classes,
System.StrUtils,
BCP47Tag,
Keyman.System.LanguageCodeUtils,
KeyboardParser,
KeymanVersion,
Keyman.Developer.System.Project.kpsProjectFile,
Keyman.Developer.System.Project.ProjectFile,
Keyman.Developer.System.Project.ProjectFiles,
RedistFiles,
TouchLayout,
utilstr,
VisualKeyboard;
{ TProjectTemplate }
constructor TProjectTemplate.Create(const BasePath, ID: string);
begin
inherited Create;
FBasePath := IncludeTrailingPathDelimiter(ExpandFileName(BasePath));
FID := ID;
FVersion := '1.0';
end;
function TProjectTemplate.GetFilename(Base: string): string;
begin
if Base = '' then
Result := ''
else if ExtractFileExt(Base) = Base then
Result := FBasePath + FID + '\' + SFolder_Source + '\' + FID + Base
else
Result := FBasePath + FID + '\' + SFolder_Source + '\' + Base;
end;
function TProjectTemplate.GetPackageFilename: string;
begin
Result := GetFilename(Ext_PackageSource);
end;
function TProjectTemplate.GetProjectFilename: string;
begin
// Project file goes in parent folder
Result := FBasePath + FID + '\' + FID + Ext_ProjectSource;
end;
procedure TProjectTemplate.WriteDocumentation;
begin
// Write readme.htm and welcome.htm
Transform(SFolder_Source + '\' + SFile_WelcomeHTM);
Transform(SFolder_Source + '\' + SFile_ReadmeHTM);
end;
procedure TProjectTemplate.SetPackageLanguageMetadata(kps: TKpsFile; languages: TPackageKeyboardLanguageList);
var
tag, tags, s: string;
bcp47tag: TBCP47Tag;
pkl: TPackageKeyboardLanguage;
begin
tags := Trim(FBCP47Tags);
tag := StrToken(tags, ' ');
while tag <> '' do
begin
pkl := TPackageKeyboardLanguage.Create(kps);
bcp47tag := TBCP47Tag.Create(tag);
try
bcp47tag.Canonicalize;
pkl.ID := bcp47tag.Tag;
if not TLanguageCodeUtils.BCP47Languages.TryGetValue(bcp47tag.Language, pkl.Name) then
begin
pkl.Name := bcp47tag.Language;
end;
if bcp47tag.Script <> '' then
begin
if TLanguageCodeUtils.BCP47Languages.TryGetValue(bcp47tag.Script, s) then
pkl.Name := pkl.Name + ' ('+s+')';
end;
finally
bcp47tag.Free;
end;
languages.Add(pkl);
tag := StrToken(tags, ' ');
end;
end;
procedure TProjectTemplate.WriteRepositoryMetadata;
begin
Transform(SFile_HistoryMD);
Transform(SFile_LicenseMD);
Transform(SFile_ReadmeMD);
end;
function TProjectTemplate.DataPath: string;
begin
Result := GetRedistProjectTemplatePath;
end;
procedure TProjectTemplate.Transform(const SourceFile: string; DestFile: string = '');
var
s: string;
ss: TStringStream;
function GetLanguageTagListForKeyboardInfo: string;
var
tags, tag: string;
bcp47tag: TBCP47Tag;
begin
// We won't worry about line breaks...
tags := Trim(FBCP47Tags);
tag := StrToken(tags, ' ');
Result := '';
while tag <> '' do
begin
if Result <> '' then
Result := Result + ', ';
bcp47tag := TBCP47Tag.Create(tag);
try
bcp47tag.Canonicalize;
Result := Result + '"' + bcp47tag.Tag + '"';
finally
bcp47tag.Free;
end;
tag := StrToken(tags, ' ');
end;
end;
function GetPlatformsDotListForReadme: string;
var
kt: TKeymanTarget;
begin
Result := '';
for kt := Low(TKeymanTarget) to High(TKeymanTarget) do
begin
if kt = ktAny then
Continue;
Result := Result + ' * ' + SKeymanTargetNames[kt] + #13#10;
end;
end;
begin
if DestFile = '' then
DestFile := SourceFile;
ss := TStringStream.Create('', TEncoding.UTF8);
try
ss.LoadFromFile(DataPath + SourceFile);
s := ss.DataString;
finally
ss.Free;
end;
s := ReplaceStr(s, '$NAME', FName);
s := ReplaceStr(s, '$VERSION', FVersion);
s := ReplaceStr(s, '$COPYRIGHT', FCopyright);
s := ReplaceStr(s, '$AUTHOR', FAuthor);
s := ReplaceStr(s, '$DATE', FormatDateTime('yyyy-mm-dd', Now));
if Pos('$LANGUAGES_KEYBOARD_INFO', s) > 0 then
s := ReplaceStr(s, '$LANGUAGES_KEYBOARD_INFO', GetLanguageTagListForKeyboardInfo);
if Pos('$PLATFORMS_DOTLIST_README', s) > 0 then
s := ReplaceStr(s, '$PLATFORMS_DOTLIST_README', GetPlatformsDotListForReadme);
ss := TStringStream.Create(s, TEncoding.UTF8);
try
ss.SaveToFile(FBasePath + FID + '\' + DestFile);
finally
ss.Free;
end;
end;
end.

View file

@ -0,0 +1,6 @@
$NAME Change History
====================
$VERSION ($DATE)
----------------
* Created by $AUTHOR

View file

@ -0,0 +1,21 @@
The MIT License (MIT)
$COPYRIGHT
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View file

@ -0,0 +1,18 @@
$NAME lexical model
===================
$COPYRIGHT
Version $VERSION
Description
-----------
$NAME generated from template
Links
-----
Supported Platforms
-------------------
$PLATFORMS_DOTLIST_README

View file

@ -0,0 +1,7 @@
{
"license": "mit",
"languages": [
$LANGUAGES_KEYBOARD_INFO
],
"description": "$NAME generated from template"
}

View file

@ -0,0 +1,13 @@
/*
$NAME $VERSION generated from template.
This is a minimal lexical model source that uses a tab delimited wordlist.
See documentation online at https://help.keyman.com/developer/ for
additional parameters.
*/
const source: LexicalModelSource = {
format: 'trie-1.0',
sources: ['wordlist.tsv'],
};
export default source;

View file

@ -0,0 +1,23 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>$NAME</title>
<style type="text/css">
p { font: 10pt Tahoma; }
h1 { font: bold 16pt Tahoma; color: #4444cc; margin-bottom: 2px }
h2 { font: bold 12pt Tahoma; color: #4444cc; }
</style>
</head>
<body>
<h1>$NAME</h1>
<p>
$NAME $VERSION generated from template.
</p>
<p>$COPYRIGHT</p>
</body>
</html>

View file

@ -0,0 +1,27 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Start Using $NAME</title>
<style type="text/css">
p { font: 10pt Tahoma; }
h1 { font: bold 16pt Tahoma; color: #4444cc; margin-bottom: 2px }
h2 { font: bold 12pt Tahoma; color: #4444cc; }
</style>
</head>
<body>
<h1>Start Using $NAME</h1>
<p>
$NAME $VERSION generated from template.
</p>
<h1>Keyboard Layout</h1>
<!-- Insert Keyboard Layout Images or HTML here -->
<p>$COPYRIGHT</p>
</body>
</html>

View file

@ -0,0 +1,16 @@
#
# $NAME $VERSION generated from template.
#
# This is an example tab-separated wordlist file that can be edited in a spreadsheet
# program or regenerated from a wordlist tool. See lexical model documentation at
# https://help.keyman.com/developer/ for tools.
#
# Columns
# =======
# WORD FREQUENCY (Optional)NOTES
#
the 100
example 5
hello 10
world 8
wordlist 3
Can't render this file because it has a wrong number of fields in line 10.

View file

@ -54,6 +54,10 @@ const
Ext_ProjectSourceUser = '.kpj.user';
Ext_Javascript = '.js';
Ext_LexicalModelSource = '.ts'; // can't use .model.ts unless we change all extension comparisons to support multiple dots...
Ext_LexicalModelSource_FULL = '.model.ts'; // TODO: Refactor these two constants
Ext_LexicalModelWordlist = '.tsv';
Ext_LexicalModelPackageSource = '.model.kps';
Ext_LexicalModelProject = '.model.kpj';
const ExtFileTypes: array[0..13] of TKMFileTypeInfo = (
(Ext: Ext_KeymanSource; FileType: ftKeymanSource),
@ -87,7 +91,7 @@ type
end;
type
TKeymanProjectType = (kptUnknown, kptBasic, kptBlank, kptImportWindowsKeyboard);
TKeymanProjectType = (kptUnknown, kptBasic, kptBlank, kptImportWindowsKeyboard, kptBlankLexicalModel, kptWordlistLexicalModel);
implementation

View file

@ -14,6 +14,10 @@ type
'The model source file %0:s does not follow the recommended model filename conventions. The name should be all lower case, '+
'include only alphanumeric characters and underscore (_), and should have the structure <author>.<bcp47>.<uniq>.model.ts';
const SProjectFileNameDoesNotFollowLexicalModelConventions_Message: string =
'The model project file %0:s does not follow the recommended model filename conventions. The name should be all lower case, '+
'include only alphanumeric characters and underscore (_), and should have the structure <author>.<bcp47>.<uniq>.model.kpj';
class function LexicalModelFileNameToID(filename: string): string;
class function LexicalModelIDToFileName(id: string): string;
class function DoesPackageFilenameFollowLexicalModelConventions(
@ -22,6 +26,8 @@ type
const Name: string): Boolean; static;
class function DoesTSFilenameFollowLexicalModelConventions(
const Name: string): Boolean; static;
class function DoesProjectFilenameFollowLexicalModelConventions(
const Name: string): Boolean; static;
end;
implementation
@ -37,9 +43,10 @@ const
// The model ID SHOULD adhere to this pattern (see also developer/js/index.ts):
// author .bcp47 .uniq
MODEL_ID_PATTERN_JS = '^[a-z_][a-z0-9_]*\.[a-z_][a-z0-9_]*\.[a-z_][a-z0-9_]*\.model\.(js)$';
MODEL_ID_PATTERN_TS = '^[a-z_][a-z0-9_]*\.[a-z_][a-z0-9_]*\.[a-z_][a-z0-9_]*\.model\.(ts)$';
MODEL_ID_PATTERN_JS = '^[a-z_][a-z0-9_]*\.[a-z_][a-z0-9_]*\.[a-z_][a-z0-9_]*\.model\.js$';
MODEL_ID_PATTERN_TS = '^[a-z_][a-z0-9_]*\.[a-z_][a-z0-9_]*\.[a-z_][a-z0-9_]*\.model\.ts$';
MODEL_ID_PATTERN_PACKAGE = '^[a-z_][a-z0-9_]*\.[a-z_][a-z0-9_]*\.[a-z_][a-z0-9_]*\.model\.(kps|kmp)$';
MODEL_ID_PATTERN_PROJECT = '^[a-z_][a-z0-9_]*\.[a-z_][a-z0-9_]*\.[a-z_][a-z0-9_]*\.model\.kpj$';
class function TLexicalModelUtils.DoesJSFilenameFollowLexicalModelConventions(
const Name: string): Boolean;
@ -61,6 +68,12 @@ begin
Result := TRegEx.IsMatch(ExtractFileName(Name), MODEL_ID_PATTERN_PACKAGE);
end;
class function TLexicalModelUtils.DoesProjectFilenameFollowLexicalModelConventions(
const Name: string): Boolean;
begin
Result := TRegEx.IsMatch(ExtractFileName(Name), MODEL_ID_PATTERN_PROJECT);
end;
class function TLexicalModelUtils.LexicalModelFileNameToID(filename: string): string;
begin
Result := ExtractFileName(filename);