Jump to content
Anders Melander

ANN: Better Translation Manager released

Recommended Posts

On 5/30/2022 at 1:35 PM, roynielsen2000@gmail.com said:

Hi,

 

I'm testing the translation tool and may have encountered a problem with the commandline tool, it ignores the -n filename scheme paramterer ?

It doesn't matter if I use -n:1 or -n 1 (or 0 or 2 as the value), I always get the 3 letter extension for the translation files

 

c:\Program Files (x86)\Melander\Better Translation Manager>amResourceModuleBuilder.exe c:\PicassoSVN\local\Localization\Reception\Reception.xlat -b -v -o:c:\PicassoSVN\local\ExeFiles\emb\ -n 1
amTranslationManager resource module builder version 1.3.8055.21506

Loading project: Reception...
Project information:
  Source file    : c:\PicassoSVN\local\ExeFiles\Reception.exe
  Source Language: Locale=0409, Name=English (United States)
  Symbol file    : .\Reception.drc
  Target language: Translated=22.585, Locale=0406, Name=Danish (Denmark)
  Target language: Translated=11.844, Locale=041D, Name=Swedish (Sweden)
  Target language: Translated=11.266, Locale=0414, Name=Norwegian Bokmål (Norway)
  Modules        :    501
  Items          : 26.765
  Properties     : 33.866
Output folder: c:\PicassoSVN\local\ExeFiles\emb\
Building resource module for Danish (Denmark): Reception.DAN...
Building resource module for Swedish (Sweden): Reception.SVE...
Building resource module for Norwegian Bokmål (Norway): Reception.NOR...
Done

Hi Anders,

 

It seems as if this bug is back again with the newest build ?

Share this post


Link to post
4 hours ago, roynielsen2000@gmail.com said:

It seems as if this bug is back again with the newest build ?

Not really. You are just using an older version of the command line tool 🙂

4 hours ago, roynielsen2000@gmail.com said:

amTranslationManager resource module builder version 1.3.8055.21506

The latest version is 1.3.8198.28909.

My guess is that you selected the installation type "Full installation" which doesn't include the command line tool. That's not intuitive so I'll change that. In the meantime just select the command line tool manually in the installer list.

Share this post


Link to post

Still the same issue:

 

c:\Program Files (x86)\Melander\Better Translation Manager>amResourceModuleBuilder.exe c:\PicassoSVN\local\Localization\Reception\Reception.xlat -b -v -o:c:\PicassoSVN\local\ExeFiles\emb\ -n 1
amTranslationManager resource module builder version 1.3.8198.28909

Loading project: Reception...
Project information:
  Source file    : c:\PicassoSVN\local\ExeFiles\Reception.exe
  Source Language: Locale=0409, Name=English (United States)
  Symbol file    : .\Reception.drc
  Target language: Translated=19.339, Locale=0406, Name=Danish (Denmark)
  Target language: Translated=     0, Locale=0814, Name=Norwegian Nynorsk (Norway)
  Target language: Translated=     0, Locale=042D, Name=Basque (Basque)
  Target language: Translated=     0, Locale=041D, Name=Swedish (Sweden)
  Target language: Translated=     0, Locale=041F, Name=Turkish (Turkey)
  Modules        :    500
  Items          : 26.785
  Properties     : 33.886
Output folder: c:\PicassoSVN\local\ExeFiles\emb\
Building resource module for Danish (Denmark): Reception.DAN...
Building resource module for Norwegian Nynorsk (Norway): Reception.NON...
Building resource module for Basque (Basque): Reception.EUQ...
Building resource module for Swedish (Sweden): Reception.SVE...
Building resource module for Turkish (Turkey): Reception.TRK...
Done

Share this post


Link to post
6 minutes ago, roynielsen2000@gmail.com said:

c:\Program Files (x86)\Melander\Better Translation Manager>amResourceModuleBuilder.exe c:\PicassoSVN\local\Localization\Reception\Reception.xlat -b -v -o:c:\PicassoSVN\local\ExeFiles\emb\ -n 1

Remove the space between -n and 1. Like so: -n1 or -n:1

I'm using FindCmdLineSwitch(<name>, Value, True, [clstValueAppended]) to fetch the parameters.

Share this post


Link to post

Hi Anders,

 

the new version 1.3.8198.28909 will add resources like "BBABORT, BBALL"  to the left side Module panel after Build.

The version 1.3.8185.25123 does not.

If you press Update after the build an exception will happen also.

 

Is it possible to add an edit mode for the translations to the Translation Memory form? Currently I can only view sort Import and Export.

 

Thanks

Karlheinz

 

Screenshot 2022-06-16 071602.jpg

Share this post


Link to post
2 hours ago, KHJ said:

the new version 1.3.8198.28909 will add resources like "BBABORT, BBALL"  to the left side Module panel after Build.

The version 1.3.8185.25123 does not.

If you press Update after the build an exception will happen also. 

Those are the standard Delphi Bitmap resources and since I'm only importing RCDATA (Forms) and Strings (resourcestrings) resources, and I'm specifically asking Windows to only return a list of those, the problem is probably some sort of memory corruption.

 

I have not been able to reproduce the problem. If you can mail me your application (zipped) I will try to reproduce with that.

 

2 hours ago, KHJ said:

Is it possible to add an edit mode for the translations to the Translation Memory form? Currently I can only view sort Import and Export.

If you click on an already focused cell (i.e. a slow double click) then the cell will go into edit mode. Pressing F2 will also do that.

 

The "slow double click" thing is a very annoying DevExpress "feature" and I usually apply a work around to fix it (e.g. I've done that in the main edit grid). It's been reported a million times but they refuse to fix it or even acknowledge that there is a problem. Anyway, I'll apply the work around to the TM form too.

Share this post


Link to post

 

2 hours ago, Anders Melander said:

If you can mail me your application (zipped) I will try to reproduce with that.

I have sent a download link.

 

2 hours ago, Anders Melander said:

I'll apply the work around to the TM form too

F2 did the trick, and thanks for the workaround. 

Share this post


Link to post

Hi,

A question:

We have several applications that share the same modules/TForm's, Is there any way to import from a module in one application to the application we are translating ?

 

Share this post


Link to post
34 minutes ago, roynielsen2000@gmail.com said:

We have several applications that share the same modules/TForm's, Is there any way to import from a module in one application to the application we are translating ?

I don't know what output Sisulizer produces but if it works like BTM/ETM/ITE and produces resource modules (i.e. DLLs) then you can use "Tools -> Import application".

Otherwise I guess you'll have to export from Sisulizer to TBX, import the TBX to the Translation Memory and then use that to translate the modules.

Share this post


Link to post
2 hours ago, KHJ said:

I have sent a download link.

Thanks. I have not been able to reproduce the problem with your application or its translation project, using the same version of BTM as you - or the newer. I can see from your application that the BB* modules are in fact RCDATA resources containing PNG images. Since I verify the signature of the resource data to determine if it's a Delphi form these should all have been excluded by the resource scanner.

 

On reviewing the code the only way I can see that this problem would occur is if the resources contained data smaller than a dword. Could it be that you updated the project on a UPX compressed (or something like it) application file?

 

I could reproduce the access violation if I opened your modified project (the one with the BB modules) and then updated the project (which correctly marked the BB modules "don't translate") but this doesn't explain how they got introduced in the first place.

 

In any case I have now added an extra check to handle RCDATA smaller than 4 bytes. New version uploaded.

Share this post


Link to post
12 hours ago, Anders Melander said:

n any case I have now added an extra check to handle RCDATA smaller than 4 bytes. New version uploaded.

 

I installed the new version and tested it. 

The same problem does exist.

 

12 hours ago, Anders Melander said:

Could it be that you updated the project on a UPX compressed (or something like it) application file?

No. The files are a direct output from Delphi 11.1. 

The older versions from BTM are working with the same file.

 

Share this post


Link to post

I verified it with a complete new and "empty" project.

Delphi => File => New => Windows VCL Application Delphi 

JCL Debug informations disabled.

DCR activated and nothing more.

 

665313195_Screenshot2022-06-17200431.thumb.jpg.fb24a98af4d0d13840d9e2ca64a0b723.jpg

 

 

 

Share this post


Link to post
19 minutes ago, KHJ said:

I verified it with a complete new and "empty" project.

Delphi => File => New => Windows VCL Application Delphi 

JCL Debug informations disabled.

DCR activated and nothing more.

I'm stumped. I don't believe the EXE-file is the problem because I can't reproduce with the one you sent me.

Which version of Windows are you on?

 

12 hours ago, KHJ said:

The older versions from BTM are working with the same file.

I know which change probably caused this. Previously, after the resource scan, I discarded modules (i.e. forms) that had no translatable items (i.e. components/properties). Now I keep them.

However that doesn't explain why the modules aren't being discarded during the resource scan since they are not DFM resources. The first thing I do when I examine a RCDATA resource item is to check if the resource starts with "TPF0" which is the binary DFM signature. If the signature isn't present then the module type is set to "other" and the module is discarded.

If I load your project, containing the BB modules, and then do an update the BB modules are immediately marked as missing since BTM considers these modules as not being present in the EXE (which is correct).

Share this post


Link to post
Posted (edited)
15 minutes ago, Anders Melander said:

Which version of Windows are you on?

Windows 1o Pro  64 bit

Version 21H2

with the last updates 

From the Systeminformation => Version 10.0.19044 Build 19044 

from the  Info page 19044.1766 

 

1379209487_Screenshot2022-06-17205046.thumb.jpg.bf81c3fd0a8b521648db4ca39e4ae9cc.jpg

 

Edited by KHJ

Share this post


Link to post
20 minutes ago, Anders Melander said:

However that doesn't explain why the modules aren't being discarded during the resource scan since they are not DFM resources.

Only to be clear:

the empty project as explained

Start BTM

New Project

- 2 Modules 357 Items 358 Properties

- only resourcestrings and TFORM1 are in the Module pane

Press Update => nothing new

Press Build All Languages  => like the picture as shown with DVCLAL to PLATFORMTARGETS marked as Translate

Press Update => the 6 modules are marked as unused 

Press Purge => the modules will deleted

Press Build All Languages => and they are back

 

 

 

 

 

Share this post


Link to post
1 hour ago, KHJ said:

Press Build All Languages  => like the picture as shown with DVCLAL to PLATFORMTARGETS marked as Translate

Ah... That was the missing piece. Reproduced!

Share this post


Link to post
6 hours ago, Anders Melander said:

Fixed and new version uploaded. Thanks for the patience

Verified 🙂

Thanks for your work and the really good tool !!!

Share this post


Link to post
On 3/6/2022 at 10:10 PM, Anders Melander said:

Now there are 🙂 Do something like this:


// Via TApplicationEvents component:
procedure TMainForm.ApplicationEventsActionExecute(Action: TBasicAction; var Handled: Boolean);
begin
{$ifdef DEBUG}
  TranslationManagerIntegration.TrackControl(Action);
{$endif DEBUG}
end;
...

Note: Remove the DEVEXPRESS define in Horizon.IntegrationTest.API if you're not using that library.

As you can see the above only uses the integration in DEBUG builds but since I'm just using WM_COPYDATA for communication it's pretty harmless if the integration is also active in RELEASE builds.

 

It works, that is really great!

 

I have also add a Ctrl + right-mouse-click to find labels etc.:

procedure TdmMain.ApplicationEvents1Message(var Msg: tagMSG; var Handled: Boolean);
 var PointClient: tPoint;
     Control: tControl;
     Form: tWinControl;
 begin
 {$IFDEF PrekladyBTM}
  if (msg.message=WM_RBUTTONDOWN) and ((msg.wParam and MK_CONTROL) <> 0) then begin
   Handled:=true;
   Form:=Screen.ActiveCustomForm;
   if Form<>nil then begin
    PointClient:=Form.ScreenToClient(Mouse.CursorPos);
    Control:=Form.ControlAtPos(PointClient, true, true, true);
    if Control<>nil then TranslationManagerIntegration.TrackControl(Control);
   end;
  end;
 {$ENDIF}
end;

 

Just a small notice: when I need to find a control and there are more properties in BTM, BTM often selects a property with "Don't translate". Please could you change it, so that BTM tries to select a property which should be translated?

image.thumb.png.a512a446a40961d1eb947ed392299f28.png

 

Share this post


Link to post
3 hours ago, Vandrovnik said:

I have also add a Ctrl + right-mouse-click to find labels etc.:

Nice. I believe you can just use the FindDragTarget VCL function to find the control under the cursor.

 

3 hours ago, Vandrovnik said:

Just a small notice: when I need to find a control and there are more properties in BTM, BTM often selects a property with "Don't translate". Please could you change it, so that BTM tries to select a property which should be translated?

The current algorithm looks for an exact match on the control name and then iterates backward (i.e. negative row index increment) from the least property until it finds a visible property. It does not consider the Status of the property since it doesn't know what you're doing or why you want to select the item. I'd like to keep it that way.
If you filter the Status column to exclude "Don't translate" then these properties will not be selected and it will behave like you want. Since you're not interested in the "Don't translate" items anyway there's no point in displaying them.

Share this post


Link to post
13 hours ago, Anders Melander said:

Nice. I believe you can just use the FindDragTarget VCL function to find the control under the cursor.

 

The current algorithm looks for an exact match on the control name and then iterates backward (i.e. negative row index increment) from the least property until it finds a visible property. It does not consider the Status of the property since it doesn't know what you're doing or why you want to select the item. I'd like to keep it that way.
If you filter the Status column to exclude "Don't translate" then these properties will not be selected and it will behave like you want. Since you're not interested in the "Don't translate" items anyway there's no point in displaying them.

Thank you, I did not realize that it is possible to use a filter 🙂 That will be enough.

Share this post


Link to post

Hi,

 

Probably a dumb question:

 

If I have a TcxGridDBTableView, how do I translate the column headers in the grid ?

Looking in my project(s) on the relevant forms containing the component 

Share this post


Link to post
Posted (edited)
6 hours ago, roynielsen2000@gmail.com said:

If I have a TcxGridDBTableView, how do I translate the column headers in the grid ?

Excellent question 🙂

 

First of all I would recommend that you use the TField.DisplayLabel property instead of the column Caption property unless you have a good reason not to. If you use TField.DisplayLabel then all columns that are bound to that field will automatically use that value as their caption and as a bonus you will only have to translate that value one place.

 

The reason you're not seeing the Caption property of the TcxGrid*Column components is that the value isn't stored in the DFM and BTM can only see the properties that are stored in the DFM...

Now, why isn't it stored? Well, the value has most likely been omitted from the DFM because it's the same as the FieldName. If you look at the TcxCustomGridTableItem.Caption property you will see that it has a stored directive. The stored directive controls if the property is stored in the DFM. In this case it will be stored if you have specified an explicit value and this value is different from the default value. So what is the default value? In this case the default value comes from the DisplayLabel property of the TDataSet field you have bound the column to. Again, if you haven't specified an explicit TField.DisplayLabel then the value of DefaultLabel defaults to TField.FieldName, in which case that value is also omitted from the DFM.

 

Now you might think that the solution is to just specify an explicit Caption or DisplayLabel and that will probably work in most cases. However it will not work in the cases where this value is the same as the FieldName, because then the default rule will again cause it to be omitted from the DFM since it isn't needed.

 

The solution is to "synthesize" the properties that have been omitted. By synthesize them I mean inject the "missing" properties into the translation project as if they were present in the DFM. If you go into the BTM settings there's an option to have BTM synthesize missing properties for you:

image.thumb.png.1e0531e2cea72cf5b2fc0df36494237f.png

The way it works is that when BTM reads the forms of the source application (e.g. during an Update), it runs the synthesize rules against each component that it find in the form. If a rule determines that a property is missing then a property is injected into the project with the specified name and value.
I believe the above screenshot shows the default rule (preinstalled, but disabled by default):

  • Type mask: ^T([A-Z][a-z]+)+Field$
    A regular expression matching a component type.
    In this case the expression will match the different TField components (TIntegerField, TStringField, etc).

  • Property name: DisplayLabel
    A property name. If this property is missing then it will be created in the translation project.

  • Property value: @FieldName
    The value to assign the property. This can be an explicit value or the value of another property.
    In this case the @ specifies that we want the value of another property, namely the FieldName property.

So let's say your application had a DFM with the following:

...
  object MyQuery: TFDQuery
    SQL.Strings = ('select name from users')
    object MyQueryUserName: TStringField
      FieldName = 'name'
      Size = 50
    end
  end
...

with the synthesize rules enabled BTM would import the above as if it looked like this:

...
  object MyQuery: TFDQuery
    SQL.Strings = ('select name from users')
    object MyQueryUserName: TStringField
      FieldName = 'name'
      DisplayLabel = 'name'
      Size = 50
    end
  end
...

Synthesized properties can be identified in the grid by their color (I believe the light green is the default - it can be customized):
image.thumb.png.91c1a9672cb493100dae0e1cf39ab934.png

 

One thing to be aware of is that the synthesize option currently is an application level setting. This means that if you only enable it on one system and then update the project on another then the synthesized properties will be marked "Unused" which means that they will be removed if you Purge the project. I'll be fixing that "real soon now".
If you run BTM in portable mode and include the portable config file in your version control (which I would recommend), then the above should not become a problem. Speaking from experience :-/

 

If you prefer to do the translation on the TcxGrid*Column level then you can use the following rule:

  • Type mask: ^TcxGrid[a-zA-Z]*Column$

  • Property name: Caption

  • Property value: @DataBinding.FieldName

It seems there is a minor bug with adding synthesize rules so after adding the rule you should restart BTM and everything should be fine. I'll look into that. Fixed (but not yet built and uploaded).

Edited by Anders Melander
  • Like 1

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×