pyscripter 689 Posted October 5, 2021 (edited) I found a bug in Gnugettext and I thought I would let you know and ask your opinion about my fix. Gnugettext does not translate Action linked properties. It does that by calling a function ObjectHasAssignedAction and in TGnuGettextInstance.TranslateProperties there is the following code: if ObjectHasAssignedAction(AnObject, PropList, Count) then Continue; The problem is that if an object has an assigned Action property no property of that object gets translated action-linked or not. I got bitten by this since there was an action in PyScripter used in different menus, and in one of them I had overwritten the Caption, so the Caption of that item was in the dfm file and the default.po, but it did not get translated. The solution I am trying with success is to remove the above code in TranslateProperties and instead added a check as to whether the property is stored (IsStoredProp😞 if ((currentcm=nil) or (not currentcm.PropertiesToIgnore.Find(UPropName,i))) and (not TP_IgnoreList.Find(Name+'.'+UPropName,i)) and IsStoredProp(AnObject, PropInfo) and (not ObjectPropertyIgnoreList.Find(UPropName,i)) then begin TranslateProperty (AnObject,PropInfo,TodoList,TextDomain); I did check that action-linked properties are not translated multiple times (IsStoredProp returns False). The above also appears to speeds up the translation. But I do wonder whether the above fix has any obvious drawbacks. @dummzeuch Any thoughts? Edited October 5, 2021 by pyscripter 1 Share this post Link to post
shineworld 73 Posted October 5, 2021 (edited) I haven't followed this way but another way for Action Caption and also for Combobox items and so on. The issue is that translations work one time, when contents are in English (starting language) to any other language (for eg: EN to IT) because they are initially copied from DFM to object fields. When I try to switch EN to IT and then to CZ for objects which don't recover data from DFM translations obviously doesn't work. But there is a solution that I use: TPageProjectWorkFrame = class(TFrame) ... private procedure ReTranslateEvent(Sender: TObject); ... end; uses gnugettext, ... osGNUGetTextUtils; constructor TPageProjectWorkFrame.Create(AOwner: TComponent); begin inherited; ... // links object/event to translate manager and re-translate GNURetranslateManager.Add(Self, ReTranslateEvent); GNURetranslateManager.ReTranslate; end; destructor TPageProjectWorkFrame.Destroy; begin // unlinks object/event from translate manager GNURetranslateManager.Remove(Self, ReTranslateEvent); ... end; procedure TPageProjectWorkFrame.ReTranslateEvent(Sender: TObject); begin AnalysisAction.Caption := _('ANALYSIS'); BackAction.Caption := _('BACK'); CoordinatesModeAction.Caption := _('WCS MODE') HomingAAction.Caption := _('HOMING A'); HomingAction.Caption := _('HOMING'); HomingAllAction.Caption := _('HOMING ALL'); HomingBAction.Caption := _('HOMING B'); HomingCAction.Caption := _('HOMING C'); HomingXAction.Caption := _('HOMING X'); HomingYAction.Caption := _('HOMING Y'); HomingZAction.Caption := _('HOMING Z'); JogAction.Caption := _('JOG'); MacroAction.Caption := _('MACRO'); ShowWork3DAction.Caption := _('WORK 3D'); ShowWorkSimulateAction.Caption := _('SIMULATE'); end; The GNURetranslateManager is a singleton object which call registered objects RetranslateEvent every time a language change. GNURetranslateManager call internally TranslateComponents (first call) or ReTranslateComponents (next call) automatically for all objects which starts always from DFM english texts (as Label, Panels, etc). Usually I keep Actions Caption empty in the designer (but not necessary) and when RetranslateEvent is called I add _('xxx') with original English language to translate. This automatically update linked action objects. It works perfectly with Frame and Forms (VCL, never tried FMX applications). osGNUGetTextUtils.pas Edited October 5, 2021 by shineworld 1 Share this post Link to post
pyscripter 689 Posted October 6, 2021 @shineworldThanks for your help. In fact. with the change above, I do not see any issues when changing the language say from English, to Chinese, to Italian and back. Maybe this is because of some fixes applied to dxgnugettext.pas. My version is based on the JVCL one and you can find it here. Share this post Link to post
dummzeuch 1505 Posted October 6, 2021 Thanks for your hints. Unfortunately it will take a while for me to review and possibly integrate them. I'm just back from vacation and fairly busy at the moment. Also, the official dxgettext and the fork in the JCL have by now diverged so much that it is difficult to understand the effects of changes to one of them for the other. Share this post Link to post
shineworld 73 Posted October 6, 2021 (edited) I'm using a cleaned gnugettext version from dxgettext-code-r131-trunk in sourceforge: https://sourceforge.net/p/dxgettext/code/HEAD/tree/ - I'm using an update manager in EXE so when the update copies the new locale.mo files from the server they are named locale.mo_NEW. This is because you can't overwrite a loaded locale.po when EXE is running, so in its restart, after an online update, the gnugettext.pas finds any locale.mo_NEW and renames to locale.mo before loading them. - I've added a {$INCLUDE Settings.inc} where the USES_LOCALE_ON_USER_DATA_PATH define is used, when not set, during debugging, to SWITCH locale path from %APPDATA%\... to development project path. This permits me to keep all locale.po/mo in the development sources git. The final program will use the locale path on %APPDATA%\myprogram\locale how must be. - Cleaned sources removing LINUX parts. osCustomize.pas, not added in attached files, just define LOCALE_NAME which can be the string 'locale' or 'locale-ppv' to have more locale libraries for two versions of same project (normal and vertical touch version, where more text are all uppercaese or short than normal version). gnugettext.pas languagecodes.pas osGNUGetTextUtils.pas osSysPath.pas gnugettext.pas-original Edited October 6, 2021 by shineworld Share this post Link to post