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)
Questions: * 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. http://en.wikipedia.org/wiki/Glade_Interface_Designer
- 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. http://msdn.microsoft.com/en-us/library/ms750441.aspx https://github.com/yadyn/WPF-Task-Dialog/blob/master/TaskDialog/CommandLink....
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. http://docs.wxwidgets.org/2.9.2/overview_xrc.html
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 Glade files? - Wouldn't that introduce troublesome build dependencies? - Would it be ok if these dependencies are needed only when in maintainer mode? (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 compile time? 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 Telugu.
Pros: * 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 sync.
* 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).
Cons: * 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 layout engine.
* 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
Pros: * Same as for option 1.
Cons: * 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 consistent though.
* 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.
Pros: * 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.
Cons: * 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 the form:
msgctxt "<rc-filename>:<dialog-id>:<control-id>" msgid "<x>:<y>:<width>:<height>" msgstr ""
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.
Pros: * Maybe the easiest solution to put in place.
Cons: * Totally ugly.
* Probably awful to work with to change the layout of a dialog.
* All the drawbacks of Option 2.
Hello Francois,
before I start: my comment below in no way implies that option 4 is the way to go.
On 09/12/2011 07:28 PM, Francois Gouget wrote:
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 the form:
msgctxt "<rc-filename>:<dialog-id>:<control-id>" msgid "<x>:<y>:<width>:<height>" msgstr ""
You wouldn't need a special PO file. You could put that info into a comment of the respective entry to translate using the "#." comment. http://www.gnu.org/s/hello/manual/gettext/PO-Files.html says: "Comment lines starting with #. contain comments given by the programmer, directed at the translator; these comments are called extracted comments because the xgettext program extracts them from the program's source code."
This would avoid separate files, unique IDs for all the entries and would be visible to the translator.
bye michael
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.
Pros:
- Maybe the easiest solution to put in place.
Cons:
Totally ugly.
Probably awful to work with to change the layout of a dialog.
All the drawbacks of Option 2.
On Mon, 12 Sep 2011, Michael Stefaniuc wrote: [...]
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 the form:
msgctxt "<rc-filename>:<dialog-id>:<control-id>" msgid "<x>:<y>:<width>:<height>" msgstr ""
You wouldn't need a special PO file. You could put that info into a comment of the respective entry to translate using the "#." comment.
[...]
This would avoid separate files, unique IDs for all the entries and would be visible to the translator.
This would be pretty tricky for a button like 'OK' which appears in a great many dialogs, each time in a different position. Also even if it is in the same position in two English dialogs, once translated it may need to be in different positions (due to other controls being resized). So that brings back the need for uniquely identifying a given control.
Francois Gouget fgouget@free.fr writes:
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?
There's another option: design the dialogs with enough spare room that most languages would fit, and maintain language-specific RC files for the special cases that really can't be accommodated. Ideally, a tool would be written to warn about a translation overflowing the available space, so that it can be looked into. Not very satisfying, but a lot simpler than the other options...
On 09/12/2011 08:14 PM, Alexandre Julliard wrote:
Francois Gouget fgouget@free.fr writes:
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?
There's another option: design the dialogs with enough spare room that
So we need somebody that can design dialogs. From the scope it is a similar job to the icon modernization/standardization done by Joel. Which isn't a bad thing as our dialogs have a pretty inconsistent look and feel.
most languages would fit, and maintain language-specific RC files for the special cases that really can't be accommodated. Ideally, a tool would be written to warn about a translation overflowing the available
IMHO we need this tool first to ease the work of the person cleaning up the dialogs; we don't want him/her to run away screaming after the first few dialogs.
space, so that it can be looked into. Not very satisfying, but a lot simpler than the other options...
And has the buy in of the Wine maintainer... SHIP IT! ;)
bye michael