Skip to content

Commit f774951

Browse files
authored
Update Google Translator (#9)
* Migrate from deprecated Google Translate API v1 to Google Cloud Translation API v2 * Add Google Cloud Translation API key support in options dialog of i18nEditor * Refine README for clarity and consistency
1 parent 1386ff2 commit f774951

16 files changed

Lines changed: 373 additions & 298 deletions

Editor/DataModule.pas

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ TDM = class(TDataModule)
5353
SortGrouping: Boolean;
5454
SortImmediately: Boolean;
5555
BulkActions: Integer;
56+
GoogleAPIKey: String;
5657
procedure LoadPersistentUserChoices;
5758
procedure SavePersistentUserChoices;
5859
procedure CopyFlagTo(Culture: TCultureInfo; dstImages: TCustomImageList;
@@ -209,6 +210,8 @@ procedure TDM.LoadPersistentUserChoices;
209210
SortGrouping := R.ReadBool('SortGrouping');
210211
if R.ValueExists('BulkActions') then
211212
BulkActions := R.ReadInteger('BulkActions');
213+
if R.ValueExists('GoogleAPIKey') then
214+
GoogleAPIKey := R.ReadString('GoogleAPIKey');
212215
R.CloseKey;
213216
end;
214217
finally
@@ -243,6 +246,10 @@ procedure TDM.SavePersistentUserChoices;
243246
R.WriteBool('SortGrouping', SortGrouping);
244247
R.WriteBool('SortImmediately', SortImmediately);
245248
R.WriteInteger('BulkActions', BulkActions);
249+
if GoogleAPIKey <> '' then
250+
R.WriteString('GoogleAPIKey', GoogleAPIKey)
251+
else if R.ValueExists('GoogleAPIKey') then
252+
R.DeleteValue('GoogleAPIKey');
246253
R.CloseKey;
247254
end;
248255
finally

Editor/dlgOptions.dfm

Lines changed: 48 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ object OptionsDialog: TOptionsDialog
55
BorderStyle = bsDialog
66
BorderWidth = 8
77
Caption = 'Preferences'
8-
ClientHeight = 276
8+
ClientHeight = 290
99
ClientWidth = 412
1010
Color = clBtnFace
1111
ParentFont = True
@@ -17,7 +17,7 @@ object OptionsDialog: TOptionsDialog
1717
TextHeight = 13
1818
object ButtonsPanel: TPanel
1919
Left = 0
20-
Top = 243
20+
Top = 257
2121
Width = 412
2222
Height = 33
2323
Align = alBottom
@@ -29,7 +29,7 @@ object OptionsDialog: TOptionsDialog
2929
412
3030
33)
3131
object btnCancel: TButton
32-
Left = 317
32+
Left = 305
3333
Top = 8
3434
Width = 95
3535
Height = 25
@@ -40,7 +40,7 @@ object OptionsDialog: TOptionsDialog
4040
TabOrder = 1
4141
end
4242
object btnOK: TButton
43-
Left = 216
43+
Left = 204
4444
Top = 8
4545
Width = 95
4646
Height = 25
@@ -55,31 +55,66 @@ object OptionsDialog: TOptionsDialog
5555
Left = 0
5656
Top = 0
5757
Width = 412
58-
Height = 243
58+
Height = 257
5959
ActivePage = tabGeneral
6060
Align = alClient
6161
TabOrder = 1
6262
object tabGeneral: TTabSheet
6363
Caption = 'General'
64-
object cbSortImmediately: TCheckBox
64+
object lblGoogleAPIKey: TLabel
6565
AlignWithMargins = True
6666
Left = 16
6767
Top = 12
6868
Width = 372
69+
Height = 15
70+
Margins.Left = 16
71+
Margins.Top = 12
72+
Margins.Right = 16
73+
Margins.Bottom = 4
74+
Align = alTop
75+
Caption = 'Google cloud translation API key:'
76+
FocusControl = txtGoogleAPIKey
77+
end
78+
object txtGoogleAPIKey: TEdit
79+
AlignWithMargins = True
80+
Left = 16
81+
Top = 31
82+
Width = 372
83+
Height = 27
84+
Margins.Left = 16
85+
Margins.Top = 0
86+
Margins.Right = 16
87+
Margins.Bottom = 8
88+
Align = alTop
89+
BiDiMode = bdLeftToRight
90+
Font.Charset = ANSI_CHARSET
91+
Font.Color = clWindowText
92+
Font.Height = -16
93+
Font.Name = 'Consolas'
94+
Font.Style = []
95+
ParentBiDiMode = False
96+
ParentFont = False
97+
TabOrder = 0
98+
end
99+
object cbSortImmediately: TCheckBox
100+
AlignWithMargins = True
101+
Left = 16
102+
Top = 78
103+
Width = 372
69104
Height = 28
70105
Margins.Left = 16
71106
Margins.Top = 12
72107
Margins.Right = 16
73108
Margins.Bottom = 0
74109
Align = alTop
75110
Caption = 'Reorder the list immediately when an item is edited'
76-
TabOrder = 0
111+
TabOrder = 1
77112
WordWrap = True
78113
end
79114
object cbAskConfirmations: TCheckBox
80115
AlignWithMargins = True
81116
Left = 16
82-
Top = 44
117+
Top = 110
83118
Width = 372
84119
Height = 28
85120
Margins.Left = 16
@@ -88,13 +123,13 @@ object OptionsDialog: TOptionsDialog
88123
Margins.Bottom = 0
89124
Align = alTop
90125
Caption = 'Ask remembered confirmations again'
91-
TabOrder = 1
126+
TabOrder = 2
92127
WordWrap = True
93128
end
94129
object btnAssociate: TButton
95130
AlignWithMargins = True
96131
Left = 16
97-
Top = 151
132+
Top = 163
98133
Width = 372
99134
Height = 40
100135
Margins.Left = 16
@@ -103,7 +138,7 @@ object OptionsDialog: TOptionsDialog
103138
Margins.Bottom = 24
104139
Align = alBottom
105140
Caption = 'Associate this program with the translation catalog files'
106-
TabOrder = 2
141+
TabOrder = 3
107142
WordWrap = True
108143
OnClick = btnAssociateClick
109144
end
@@ -118,8 +153,9 @@ object OptionsDialog: TOptionsDialog
118153
'btnOK.Caption'
119154
'cbAskConfirmations.Caption'
120155
'cbSortImmediately.Caption'
156+
'lblGoogleAPIKey.Caption'
121157
'tabGeneral.Caption')
122158
Left = 2
123-
Top = 247
159+
Top = 263
124160
end
125161
end

Editor/dlgOptions.pas

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ TOptionsDialog = class(TForm)
2727
cbSortImmediately: TCheckBox;
2828
cbAskConfirmations: TCheckBox;
2929
btnAssociate: TButton;
30+
txtGoogleAPIKey: TEdit;
31+
lblGoogleAPIKey: TLabel;
3032
procedure btnAssociateClick(Sender: TObject);
3133
public
3234
class function Execute: Boolean;
@@ -42,7 +44,7 @@ implementation
4244

4345
{ Helper Functions }
4446

45-
function IsAssicoated(const FileExt, Application: String; AllUsers: Boolean): Boolean;
47+
function IsAssociated(const FileExt, Application: String; AllUsers: Boolean): Boolean;
4648
var
4749
R: TRegistry;
4850
FileType, Association: String;
@@ -75,7 +77,7 @@ function IsAssicoated(const FileExt, Application: String; AllUsers: Boolean): Bo
7577
end;
7678
end;
7779

78-
function Assicoate(const FileExt, FileType, FileDesc: String;
80+
function Associate(const FileExt, FileType, FileDesc: String;
7981
const Application: String; IconIndex: Integer; AllUsers: Boolean): Boolean;
8082
var
8183
R: TRegistry;
@@ -124,12 +126,14 @@ class function TOptionsDialog.Execute: Boolean;
124126
Result := False;
125127
with Create(Application) do
126128
try
127-
btnAssociate.Enabled := not IsAssicoated(i18nCatalogFileExt, Application.ExeName, False);
129+
txtGoogleAPIKey.Text := DM.GoogleAPIKey;
128130
cbSortImmediately.Checked := DM.SortImmediately;
129131
cbAskConfirmations.Checked := (DM.BulkActions <> 0);
130132
cbAskConfirmations.Enabled := (DM.BulkActions >= 0);
133+
btnAssociate.Enabled := not IsAssociated(i18nCatalogFileExt, Application.ExeName, False);
131134
if ShowModal = mrOK then
132135
begin
136+
DM.GoogleAPIKey := Trim(txtGoogleAPIKey.Text);
133137
DM.SortImmediately := cbSortImmediately.Checked;
134138
if cbAskConfirmations.Enabled then
135139
DM.BulkActions := Ord(cbAskConfirmations.Checked);
@@ -142,7 +146,7 @@ class function TOptionsDialog.Execute: Boolean;
142146

143147
procedure TOptionsDialog.btnAssociateClick(Sender: TObject);
144148
begin
145-
btnAssociate.Enabled := not Assicoate(i18nCatalogFileExt,
149+
btnAssociate.Enabled := not Associate(i18nCatalogFileExt,
146150
'i18n', 'i18n Catalog', Application.ExeName, 1, False);
147151
end;
148152

Editor/frmTranslationEditor.pas

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1203,6 +1203,7 @@ procedure TTranslationEditor.TargetLanguageActionUpdate(Sender: TObject);
12031203
procedure TTranslationEditor.SettingsChanged;
12041204
begin
12051205
List.SortImmediately := DM.SortImmediately;
1206+
GoogleTranslator.APIKey := DM.GoogleAPIKey;
12061207
end;
12071208

12081209
function TTranslationEditor.CanDiscardChanges: Boolean;
@@ -2097,7 +2098,6 @@ function TTranslationEditor.DoGoogleTranslate(Node: TListNode): Boolean;
20972098
var
20982099
TextToTranslate: String;
20992100
GoogleResult: String;
2100-
GoogleResultCode: TGoogleResultCode;
21012101
Group: TGroupNode absolute Node;
21022102
Item: TItemNode;
21032103
begin
@@ -2107,27 +2107,24 @@ function TTranslationEditor.DoGoogleTranslate(Node: TListNode): Boolean;
21072107
TextToTranslate := Item.Definition.Value;
21082108
if Item.Definition.HasPluralForms then
21092109
TextToTranslate := ZStrings.Split(TextToTranslate, UCC_US);
2110-
Screen.Cursor := crHourGlass;
21112110
try
2112-
GoogleResultCode := GoogleTranslator.Translate(TextToTranslate, GoogleResult);
2113-
finally
2114-
Screen.Cursor := crDefault;
2115-
end;
2116-
if GoogleResultCode = grOK then
2117-
begin
2111+
Screen.Cursor := crHourGlass;
2112+
try
2113+
GoogleResult := GoogleTranslator.Translate(TextToTranslate);
2114+
finally
2115+
Screen.Cursor := crDefault;
2116+
end;
21182117
if Item.Definition.HasPluralForms then
21192118
GoogleResult := ZStrings.Construct(GoogleResult, UCC_US);
21202119
Result := UpdateItem(Item, GoogleResult, tsGoogle, True)
2121-
end
2122-
else
2123-
begin
2124-
ProgressBar.State := pbsError;
2125-
if GoogleResultCode = grGoogleError then
2126-
DM.MsgDlg.ShowWarning(Translator.GetText(SGoogleLanguagePairError))
2127-
else
2128-
DM.MsgDlg.ShowError(Translator.GetText(SGoogleConnectError));
2129-
Result := False;
2130-
Abort;
2120+
except
2121+
on E: Exception do
2122+
begin
2123+
ProgressBar.State := pbsError;
2124+
DM.MsgDlg.ShowError(E.Message);
2125+
Result := False;
2126+
Abort;
2127+
end;
21312128
end;
21322129
end
21332130
else
@@ -2202,6 +2199,7 @@ constructor TTranslationEditor.CreateNew;
22022199
COLUMN_STATE, COLUMN_COMMENT, COLUMN_NOTE, COLUMN_NAME, COLUMN_PLURALS);
22032200
begin
22042201
inherited Create(Application);
2202+
GoogleTranslator.APIKey := DM.GoogleAPIKey;
22052203
SearchDetails.Params.Options.Fields := [sfOriginal, sfTranslated, sfName];
22062204
Catalog := TTranslationCatalog.Create;
22072205
Catalog.Repository := DM.Repository;

Editor/i18nEditor.dproj

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -72,14 +72,14 @@
7272
<Icon_MainIcon>icons\i18nEditor.ico</Icon_MainIcon>
7373
<Manifest_File>i18nEditor.manifest</Manifest_File>
7474
<VerInfo_MajorVer>2</VerInfo_MajorVer>
75-
<VerInfo_MinorVer>2</VerInfo_MinorVer>
76-
<VerInfo_Release>1</VerInfo_Release>
77-
<VerInfo_Build>0</VerInfo_Build>
75+
<VerInfo_MinorVer>3</VerInfo_MinorVer>
76+
<VerInfo_Release>0</VerInfo_Release>
7877
<VerInfo_Locale>1033</VerInfo_Locale>
79-
<VerInfo_Keys>CompanyName=;FileDescription=The translation editor for the i18n Delphi package;FileVersion=2.2.1.0;InternalName=i18nEditor;LegalCopyright=Copyright (c) Kambiz Khojasteh;LegalTrademarks=;OriginalFilename=i18nEditor.exe;ProgramID=;ProductName=i18n Editor;ProductVersion=2.2.1;Comments=https://github.com/khojasteh/i18n</VerInfo_Keys>
78+
<VerInfo_Keys>CompanyName=;FileDescription=The translation editor for the i18n Delphi package;FileVersion=2.3.0.0;InternalName=i18nEditor;LegalCopyright=Copyright (c) Kambiz Khojasteh;LegalTrademarks=;OriginalFilename=i18nEditor.exe;ProgramID=;ProductName=i18n Editor;ProductVersion=2.3.0;Comments=https://github.com/khojasteh/i18n</VerInfo_Keys>
8079
<SanitizedProjectName>i18nEditor</SanitizedProjectName>
8180
<PostBuildEvent><![CDATA[copy "$(ProjectDir)\translations\i18nEditor.i18n" "$(DCC_ExeOutput)"
8281
$(PostBuildEvent)]]></PostBuildEvent>
82+
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
8383
</PropertyGroup>
8484
<PropertyGroup Condition="'$(Base_Win32)'!=''">
8585
<BT_BuildType>Release</BT_BuildType>
@@ -120,6 +120,7 @@ $(PostBuildEvent)]]></PostBuildEvent>
120120
<PropertyGroup Condition="'$(Cfg_2_Win64)'!=''">
121121
<DCC_RemoteDebug>false</DCC_RemoteDebug>
122122
<BT_BuildType>Debug</BT_BuildType>
123+
<Manifest_File>$(BDS)\bin\default_app.manifest</Manifest_File>
123124
</PropertyGroup>
124125
<ItemGroup>
125126
<DelphiCompile Include="$(MainSource)">
@@ -191,6 +192,10 @@ $(PostBuildEvent)]]></PostBuildEvent>
191192
<Source>
192193
<Source Name="MainSource">i18nEditor.dpr</Source>
193194
</Source>
195+
<Excluded_Packages>
196+
<Excluded_Packages Name="$(BDSBIN)\dcloffice2k290.bpl">Microsoft Office 2000 Sample Automation Server Wrapper Components</Excluded_Packages>
197+
<Excluded_Packages Name="$(BDSBIN)\dclofficexp290.bpl">Microsoft Office XP Sample Automation Server Wrapper Components</Excluded_Packages>
198+
</Excluded_Packages>
194199
</Delphi.Personality>
195200
<Platforms>
196201
<Platform value="Win32">True</Platform>
@@ -207,31 +212,35 @@ $(PostBuildEvent)]]></PostBuildEvent>
207212
<PreBuildEventIgnoreExitCode>False</PreBuildEventIgnoreExitCode>
208213
<PreLinkEvent/>
209214
<PreLinkEventIgnoreExitCode>False</PreLinkEventIgnoreExitCode>
210-
<PostBuildEvent>copy &quot;$(ProjectDir)\translations\i18nEditor.i18n&quot; &quot;$(DCC_ExeOutput)&quot;</PostBuildEvent>
215+
<PostBuildEvent>copy &quot;$(ProjectDir)\translations\i18nEditor.i18n&quot; &quot;$(DCC_ExeOutput)&quot;
216+
</PostBuildEvent>
211217
<PostBuildEventIgnoreExitCode>False</PostBuildEventIgnoreExitCode>
212218
</PropertyGroup>
213219
<PropertyGroup Condition="'$(Config)'=='Debug' And '$(Platform)'=='Win64'">
214220
<PreBuildEvent/>
215221
<PreBuildEventIgnoreExitCode>False</PreBuildEventIgnoreExitCode>
216222
<PreLinkEvent/>
217223
<PreLinkEventIgnoreExitCode>False</PreLinkEventIgnoreExitCode>
218-
<PostBuildEvent>copy &quot;$(ProjectDir)\translations\i18nEditor.i18n&quot; &quot;$(DCC_ExeOutput)&quot;</PostBuildEvent>
224+
<PostBuildEvent>copy &quot;$(ProjectDir)\translations\i18nEditor.i18n&quot; &quot;$(DCC_ExeOutput)&quot;
225+
</PostBuildEvent>
219226
<PostBuildEventIgnoreExitCode>False</PostBuildEventIgnoreExitCode>
220227
</PropertyGroup>
221228
<PropertyGroup Condition="'$(Config)'=='Release' And '$(Platform)'=='Win32'">
222229
<PreBuildEvent/>
223230
<PreBuildEventIgnoreExitCode>False</PreBuildEventIgnoreExitCode>
224231
<PreLinkEvent/>
225232
<PreLinkEventIgnoreExitCode>False</PreLinkEventIgnoreExitCode>
226-
<PostBuildEvent>copy &quot;$(ProjectDir)\translations\i18nEditor.i18n&quot; &quot;$(DCC_ExeOutput)&quot;</PostBuildEvent>
233+
<PostBuildEvent>copy &quot;$(ProjectDir)\translations\i18nEditor.i18n&quot; &quot;$(DCC_ExeOutput)&quot;
234+
</PostBuildEvent>
227235
<PostBuildEventIgnoreExitCode>False</PostBuildEventIgnoreExitCode>
228236
</PropertyGroup>
229237
<PropertyGroup Condition="'$(Config)'=='Release' And '$(Platform)'=='Win64'">
230238
<PreBuildEvent/>
231239
<PreBuildEventIgnoreExitCode>False</PreBuildEventIgnoreExitCode>
232240
<PreLinkEvent/>
233241
<PreLinkEventIgnoreExitCode>False</PreLinkEventIgnoreExitCode>
234-
<PostBuildEvent>copy &quot;$(ProjectDir)\translations\i18nEditor.i18n&quot; &quot;$(DCC_ExeOutput)&quot;</PostBuildEvent>
242+
<PostBuildEvent>copy &quot;$(ProjectDir)\translations\i18nEditor.i18n&quot; &quot;$(DCC_ExeOutput)&quot;
243+
</PostBuildEvent>
235244
<PostBuildEventIgnoreExitCode>False</PostBuildEventIgnoreExitCode>
236245
</PropertyGroup>
237246
</Project>

Editor/i18nEditor.res

868 Bytes
Binary file not shown.

Editor/translations/i18nEditor.i18n

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4028,6 +4028,16 @@
40284028
<Translation Locale="be-BY">Змяніць парадак спісу адразу пасля рэдакцыі элемента</Translation>
40294029
<Translation Locale="es-ES">Reordenar la lista luego de editar uno de sus elementos</Translation>
40304030
</Property>
4031+
<Property ID="lblGoogleAPIKey.Caption">
4032+
<Value>Google cloud translation API key:</Value>
4033+
<Translation Locale="fa-IR">کلید API ترجمه ابری گوگل:</Translation>
4034+
<Translation Locale="pl-PL">Klucz API tłumaczenia w chmurze Google:</Translation>
4035+
<Translation Locale="ru-RU">Ключ API перевода Google Cloud:</Translation>
4036+
<Translation Locale="lt-LT">„Google“ debesų vertimo API raktas:</Translation>
4037+
<Translation Locale="de-DE">Google Cloud Translation API-Schlüssel:</Translation>
4038+
<Translation Locale="be-BY">Ключ API перакладу Google Cloud:</Translation>
4039+
<Translation Locale="es-ES">Clave de API de traducción de Google Cloud:</Translation>
4040+
</Property>
40314041
</Domain>
40324042
<Domain Name="PluralRuleEditorDialog">
40334043
<Property ID=".Caption">

0 commit comments

Comments
 (0)