mirror of
https://github.com/keymanapp/keyman.git
synced 2026-09-23 16:17:40 +00:00
feat(developer): check for duplicated language codes in package editor and compiler
Fixes #8119.
This commit is contained in:
parent
a040a2bb6b
commit
8ee8325c74
3 changed files with 95 additions and 44 deletions
|
|
@ -337,6 +337,8 @@ type
|
|||
procedure SaveJSON(ARoot: TJSONObject); virtual;
|
||||
procedure LoadXML(ARoot: IXMLNode); virtual;
|
||||
procedure SaveXML(ARoot: IXMLNode); virtual;
|
||||
function ContainsID(const id: string): Boolean;
|
||||
function IndexOfID(const id: string): Integer;
|
||||
end;
|
||||
|
||||
TPackageLexicalModel = class(TPackageBaseObject)
|
||||
|
|
@ -2262,6 +2264,21 @@ end;
|
|||
|
||||
{ TPackageKeyboardLanguageList }
|
||||
|
||||
function TPackageKeyboardLanguageList.ContainsID(const id: string): Boolean;
|
||||
begin
|
||||
Result := IndexOfID(id) >= 0;
|
||||
end;
|
||||
|
||||
function TPackageKeyboardLanguageList.IndexOfID(const id: string): Integer;
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
for i := 0 to Count - 1 do
|
||||
if SameText(Items[i].ID, id) then
|
||||
Exit(i);
|
||||
Result := -1;
|
||||
end;
|
||||
|
||||
procedure TPackageKeyboardLanguageList.LoadJSON(ARoot: TJSONObject);
|
||||
var
|
||||
j: Integer;
|
||||
|
|
|
|||
|
|
@ -27,7 +27,9 @@ unit CompilePackage;
|
|||
interface
|
||||
|
||||
uses
|
||||
kpsfile, kmpinffile, PackageInfo,
|
||||
kpsfile,
|
||||
kmpinffile,
|
||||
PackageInfo,
|
||||
Keyman.Developer.System.Project.ProjectLog;
|
||||
|
||||
function DoCompilePackage(pack: TKPSFile; AMessageEvent: TCompilePackageMessageEvent; ASilent, ACheckFilenameConventions: Boolean; const AOutputFileName: string): Boolean; // I4688
|
||||
|
|
@ -37,6 +39,7 @@ implementation
|
|||
uses
|
||||
Winapi.Windows,
|
||||
System.Classes,
|
||||
System.Generics.Collections,
|
||||
System.SysUtils,
|
||||
System.IniFiles,
|
||||
System.Zip,
|
||||
|
|
@ -85,6 +88,7 @@ type
|
|||
procedure CheckKeyboardLanguages;
|
||||
procedure CheckFilenameConventions;
|
||||
function CheckLexicalModels: Boolean;
|
||||
procedure CheckForDuplicatedLanguages(const resourceType, id: string; languages: TPackageKeyboardLanguageList);
|
||||
end;
|
||||
|
||||
function DoCompilePackage(pack: TKPSFile; AMessageEvent: TCompilePackageMessageEvent; ASilent, ACheckFilenameConventions: Boolean; const AOutputFileName: string): Boolean; // I4688
|
||||
|
|
@ -141,6 +145,8 @@ begin
|
|||
end;
|
||||
|
||||
function TCompilePackage.CheckLexicalModels: Boolean;
|
||||
var
|
||||
model: TPackageLexicalModel;
|
||||
begin
|
||||
if pack.LexicalModels.Count > 0 then
|
||||
begin
|
||||
|
|
@ -151,6 +157,12 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
for model in pack.LexicalModels do
|
||||
begin
|
||||
CheckForDuplicatedLanguages('model', model.id, model.Languages);
|
||||
end;
|
||||
|
||||
|
||||
Exit(True);
|
||||
end;
|
||||
|
||||
|
|
@ -487,6 +499,7 @@ end;
|
|||
const
|
||||
SKKeyboardPackageLanguageNonCanonical = 'The keyboard %0:s has a non-canonical language tag "%1:s" (%2:s), should be "%3:s".';
|
||||
SKKeyboardShouldHaveAtLeastOneLanguage = 'The keyboard %0:s has no language tags. It should have at least one language tag.';
|
||||
SKPackageShouldNotRepeatLanguages = 'The %0:s %1:s has a repeated language "%2:s".';
|
||||
|
||||
procedure TCompilePackage.CheckKeyboardLanguages;
|
||||
var
|
||||
|
|
@ -496,6 +509,30 @@ begin
|
|||
begin
|
||||
if k.Languages.Count = 0 then
|
||||
WriteMessage(plsWarning, Format(SKKeyboardShouldHaveAtLeastOneLanguage, [k.ID]));
|
||||
CheckForDuplicatedLanguages('keyboard', k.ID, k.Languages);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TCompilePackage.CheckForDuplicatedLanguages(const resourceType, id: string; languages: TPackageKeyboardLanguageList);
|
||||
var
|
||||
tags: TDictionary<string,Integer>;
|
||||
lang: TPackageKeyboardLanguage;
|
||||
begin
|
||||
tags := TDictionary<string,Integer>.Create;
|
||||
try
|
||||
for lang in languages do
|
||||
begin
|
||||
if tags.ContainsKey(lang.ID.ToLower) then
|
||||
begin
|
||||
WriteMessage(plsWarning, Format(SKPackageShouldNotRepeatLanguages, [resourceType, id, lang.ID]));
|
||||
end
|
||||
else
|
||||
begin
|
||||
tags.Add(lang.ID.ToLower, 0);
|
||||
end;
|
||||
end;
|
||||
finally
|
||||
tags.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
|
|
|||
|
|
@ -314,8 +314,7 @@ type
|
|||
procedure EnableLexicalModelTabControls;
|
||||
procedure ShowEditLanguageForm(grid: TStringGrid;
|
||||
langs: TPackageKeyboardLanguageList; lang: TPackageKeyboardLanguage);
|
||||
function ShowAddLanguageForm(grid: TStringGrid;
|
||||
langs: TPackageKeyboardLanguageList): Boolean;
|
||||
procedure ShowAddLanguageForm(grid: TStringGrid; langs: TPackageKeyboardLanguageList);
|
||||
procedure RefreshLexicalModelList;
|
||||
procedure UpdateQRCode;
|
||||
|
||||
|
|
@ -1624,6 +1623,8 @@ procedure TfrmPackageEditor.EnableControls;
|
|||
begin
|
||||
EnableStartMenuControls;
|
||||
EnableDetailsTabControls;
|
||||
EnableKeyboardTabControls;
|
||||
EnableLexicalModelTabControls;
|
||||
EnableCompileTabControls;
|
||||
end;
|
||||
|
||||
|
|
@ -1686,35 +1687,16 @@ end;
|
|||
procedure TfrmPackageEditor.cmdKeyboardAddLanguageClick(Sender: TObject);
|
||||
var
|
||||
k: TPackageKeyboard;
|
||||
lang: TPackageKeyboardLanguage;
|
||||
frm: TfrmSelectBCP47Language;
|
||||
begin
|
||||
k := SelectedKeyboard;
|
||||
Assert(Assigned(k));
|
||||
|
||||
frm := TfrmSelectBCP47Language.Create(Application.MainForm);
|
||||
try
|
||||
if frm.ShowModal = mrOk then
|
||||
begin
|
||||
lang := TPackageKeyboardLanguage.Create(pack);
|
||||
lang.ID := frm.LanguageID;
|
||||
lang.Name := frm.LanguageName;
|
||||
k.Languages.Add(lang);
|
||||
RefreshKeyboardLanguageList(k);
|
||||
gridKeyboardLanguages.Row := gridKeyboardLanguages.RowCount - 1;
|
||||
gridKeyboardLanguagesClick(gridKeyboardLanguages);
|
||||
Modified := True;
|
||||
end;
|
||||
finally
|
||||
frm.Free;
|
||||
end;
|
||||
ShowAddLanguageForm(gridKeyboardLanguages, k.Languages);
|
||||
end;
|
||||
|
||||
procedure TfrmPackageEditor.cmdKeyboardEditLanguageClick(Sender: TObject);
|
||||
var
|
||||
k: TPackageKeyboard;
|
||||
lang: TPackageKeyboardLanguage;
|
||||
frm: TfrmSelectBCP47Language;
|
||||
begin
|
||||
k := SelectedKeyboard;
|
||||
Assert(Assigned(k));
|
||||
|
|
@ -1722,20 +1704,7 @@ begin
|
|||
lang := SelectedKeyboardLanguage;
|
||||
Assert(Assigned(lang));
|
||||
|
||||
frm := TfrmSelectBCP47Language.Create(Application.MainForm);
|
||||
try
|
||||
frm.LanguageID := lang.ID;
|
||||
frm.LanguageName := lang.Name;
|
||||
if frm.ShowModal = mrOk then
|
||||
begin
|
||||
lang.ID := frm.LanguageID;
|
||||
lang.Name := frm.LanguageName;
|
||||
RefreshKeyboardLanguageList(k);
|
||||
Modified := True;
|
||||
end;
|
||||
finally
|
||||
frm.Free;
|
||||
end;
|
||||
ShowEditLanguageForm(gridKeyboardLanguages, k.Languages, lang);
|
||||
end;
|
||||
|
||||
procedure TfrmPackageEditor.cmdKeyboardRemoveLanguageClick(Sender: TObject);
|
||||
|
|
@ -1819,16 +1788,25 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
function TfrmPackageEditor.ShowAddLanguageForm(grid: TStringGrid; langs: TPackageKeyboardLanguageList): Boolean;
|
||||
procedure TfrmPackageEditor.ShowAddLanguageForm(grid: TStringGrid; langs: TPackageKeyboardLanguageList);
|
||||
var
|
||||
lang: TPackageKeyboardLanguage;
|
||||
frm: TfrmSelectBCP47Language;
|
||||
n: Integer;
|
||||
begin
|
||||
Result := False;
|
||||
frm := TfrmSelectBCP47Language.Create(Application.MainForm);
|
||||
try
|
||||
if frm.ShowModal = mrOk then
|
||||
begin
|
||||
n := langs.IndexOfID(frm.LanguageID);
|
||||
if n >= 0 then
|
||||
begin
|
||||
// Duplicate - we won't re-add the item, just select the existing item
|
||||
grid.Row := n + 1;
|
||||
EnableControls;
|
||||
Exit;
|
||||
end;
|
||||
|
||||
lang := TPackageKeyboardLanguage.Create(pack);
|
||||
lang.ID := frm.LanguageID;
|
||||
lang.Name := frm.LanguageName;
|
||||
|
|
@ -1836,7 +1814,7 @@ begin
|
|||
RefreshLanguageList(grid, langs);
|
||||
grid.Row := grid.RowCount - 1;
|
||||
Modified := True;
|
||||
Result := True;
|
||||
EnableControls;
|
||||
end;
|
||||
finally
|
||||
frm.Free;
|
||||
|
|
@ -1846,6 +1824,7 @@ end;
|
|||
procedure TfrmPackageEditor.ShowEditLanguageForm(grid: TStringGrid; langs: TPackageKeyboardLanguageList; lang: TPackageKeyboardLanguage);
|
||||
var
|
||||
frm: TfrmSelectBCP47Language;
|
||||
n: Integer;
|
||||
begin
|
||||
frm := TfrmSelectBCP47Language.Create(Application.MainForm);
|
||||
try
|
||||
|
|
@ -1853,9 +1832,30 @@ begin
|
|||
frm.LanguageName := lang.Name;
|
||||
if frm.ShowModal = mrOk then
|
||||
begin
|
||||
if not SameText(frm.LanguageID, lang.ID) then
|
||||
begin
|
||||
// If the id has changed, check for duplicates
|
||||
n := langs.IndexOfID(frm.LanguageID);
|
||||
if n >= 0 then
|
||||
begin
|
||||
// Duplicate - we will delete the edited one and select the existing
|
||||
// one
|
||||
langs.Remove(lang);
|
||||
RefreshLanguageList(grid, langs);
|
||||
|
||||
// The index may have changed, search again
|
||||
n := langs.IndexOfID(frm.LanguageID);
|
||||
grid.Row := n + 1;
|
||||
EnableControls;
|
||||
Modified := True;
|
||||
Exit;
|
||||
end;
|
||||
end;
|
||||
|
||||
lang.ID := frm.LanguageID;
|
||||
lang.Name := frm.LanguageName;
|
||||
RefreshLanguageList(grid, langs);
|
||||
EnableControls;
|
||||
Modified := True;
|
||||
end;
|
||||
finally
|
||||
|
|
@ -2005,10 +2005,7 @@ var
|
|||
begin
|
||||
lm := SelectedLexicalModel;
|
||||
Assert(Assigned(lm));
|
||||
|
||||
if ShowAddLanguageForm(gridLexicalModelLanguages, lm.Languages) then
|
||||
gridLexicalModelLanguagesClick(gridLexicalModelLanguages);
|
||||
EnableLexicalModelTabControls;
|
||||
ShowAddLanguageForm(gridLexicalModelLanguages, lm.Languages);
|
||||
end;
|
||||
|
||||
procedure TfrmPackageEditor.cmdLexicalModelLanguageEditClick(Sender: TObject);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue