RFC: Translating Wine's dialogs with PO files
fgouget at free.fr
Mon Sep 12 12:28:04 CDT 2011
This is the next step in making full use of the PO files for translating
Wine. But how to get there is unclear, hence this RFC.
The issue with dialogs is that in RC files all the dialog and control
sizes are hardcoded. For instance in the line below '208, 6, 56, 14'
represent the x-left, y-top, width and height of the button:
DEFPUSHBUTTON "Save As", IDOK, 208, 6, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP
The problem is that once translated to French, for instance, the label
becomes 'Enregistrer sous' which is much longer and may require
enlarging the button. But RC files do not contain the information needed
to do that automatically. For instance they don't specify enlarging this
button requires enlarging the 'Cancel' and 'Help' buttons below too.
So how do we solve this problem?
Option 1 - Automatically layout the dialogs at compile time
Gtk applications solve this problem by storing all the information
needed to automatically layout dialogs in an XML file. The size and
location of all the controls is then computed at runtime, after the
dialog has been translated.
We could do something similar, it would go something like this:
* Use some format that lets us store all the layout information as the
primary definition for Wine's dialogs.
* At compile time translate the dialogs.
* For each translation, layout the dialog and generate an RC file
containing the computed control coordinates and sizes.
* Then compile the RC files as usual.
(alternatively the last two steps could be merged)
* Which format should we use to define the layout?
- Glade is the format used by Gtk. However it seems pretty Gtk
centric and the set of controls/properties it supports may not
match the Windows ones. It's possible to add libraries of custom
widgets so that may be a solution.
- It looks like Microsoft added support for auto-layout in WPF
(Windows Presentation Foundation) for .Net applications. This
information can be stored in XAML XML files.
Does anyone know how this works?
Is it something we would need to implement in Wine anyway?
Does some project already have support for it? Mono maybe?
- For completeness I'll also mention that WxWidget also has a
cross-platform layout engine.
However as far as I know, none of them has tools that can
generate RC files.
* How can we do the layout?
- Can we reuse a third-party layout engine? Like the one used for
- Wouldn't that introduce troublesome build dependencies?
- Would it be ok if these dependencies are needed only when in
(In maintainer mode a change to a PO file could trigger an update
to the corresponding RC files which would then be committed with
the PO file change.)
- Should we instead implement it all by ourselves?
* How can we mesure the size that strings will take at run time?
We probably have all the code we need in Wine. But can we use it are
Will the computed layout depend on the fonts that are installed on
the system where Wine is compiled? This is particularly important for
languages with non-latin characters such as Japanese, Hebrew or
* We would not have to manually layout dialogs ever again. Yay!
* We might be able to reuse the graphical dialog design tools of
the system we adopt, like Glade or possibly some .Net tools.
* There would be no risk of the translation and layout getting out of
* We would no longer need one RC file per language, thus eliminating
the risk that they become out of sync (e.g. adding a given window
style to some but not all languages).
* Just integrating support for the layout engine and generating RC
files seems like a lot of work.
* Potential for additional build-time third-party dependencies for the
* Would require rewritting all our dialogs so they have all the needed
layout information. That is definitely a lot of work.
Option 2 - Add layout information to RC files
The idea here is the same as for option 1 except that we would add the
layout information as comments in the existing RC files. As a very
rough exemple it could look something like this:
#layout# start box(orientation = vertical, padding = 8)
#layout# start button(expand = true, fill = true)
DEFPUSHBUTTON "Save As", IDOK, 208, 6, 56, 14, BS_DEFPUSHBUTTON |
WS_GROUP | WS_TABSTOP
#layout# end button
#layout# end box
* Same as for option 1.
* We would be inventing our own syntax.
* Not as clean as option 1.
* The comments would risk becoming out of sync with the dialogs (e.g.
if a developper adds a button but not the comment specifying how it
is to be layed out). wrc might be able to check that things are
* It would be as much work as option 1.
* We would have no chance of leveraging an existing layout engine.
Option 3 - Use per-language RC files to store hardcoded dialog layouts
This solution would reuse the existing per-language RC files but would
refresh their labels using the PO files. Here is how it would work:
* Every control of a given dialog would need to have a unique id. This
should only be an issue for static labels which currently tend to all
have -1 as their id. So we would first have to reassign them
different ids like -1, -2, -3 or stc1, stc2, stc3, etc.
* For each control that has a label in a language-specific RC file,
look for the corresponding '<dialog-id>+<control-id>' combination in
the English RC file. If no match is found that's an error.
* Take corresponding English label and use the PO file to translate it.
* Use the translated label instead of the, potentially outdated, one
that was in the language-specific RC file.
* This could be done by wrc when generating a .res file. This way any
PO file change would immediately be reflected in the build.
Alternatively this could be a maintainer-only task that updates
the language-specific RC files whenever a PO file patch is committed.
We could even do both so the labels in the language-specific RC files
don't become too out of date.
* If a given dialog is missing from a language-specific RC file, we
would do as if the English dialog data was present instead and
proceed as described above.
* The current RC files would not need extensive modifications.
* In fact we could progressively simplify them by removing all the
translated dialogs that don't change the layout.
* This solution feels like it should be easier to put in place than an
automatic layout one.
* We would still need to manually layout or verify the layout of every
single dialog for every single language :-(
* The translators would have no idea that there is a dialog whose
layout may need to be changed as a result of their changes to the PO
file. Developpers would similarly be hard pressed to make the
connection and would likely lack the motivation to update the dialog
layouts. So the dialog layouts would likely continue to be rarely
updated and possibly incorrect. Exactly like today.
* For every dialog with a customized dialog the translations would be
stored both in the language-specific RC file and in the PO file. This
could be confusing.
Option 4 - Put the sizes in special PO files
This would really be a very ugly hack.
Like option 2 it requires that every control of a given dialog have a
unique id. Then for each of them we would create PO file entries of
We then put all these 'messages' in a sizes-<lang>.po file. Whenever a
control needs to be resized a 'translation' would be provided in the
relevant sizes-<lang>.po file.
We would only keep the English RC file and when compiling the resources
for a given language wrc would check whether the sizes-<lang>.po file
contains a translation of the size data for the current control.
* Maybe the easiest solution to put in place.
* Totally ugly.
* Probably awful to work with to change the layout of a dialog.
* All the drawbacks of Option 2.
Francois Gouget <fgouget at free.fr> http://fgouget.free.fr/
f u kn rd ts, ur wy 2 gky 4 ur wn gd.
More information about the wine-devel