GNOME Bugzilla – Bug 163292
Glade shouldn't populate comboboxes in one sweep
Last modified: 2011-07-19 23:01:32 UTC
I was told by chris@gnome-de.org in bug 160807 to file this bug report. As I understand it, in order to populate a combobox in Glade, you have to populate it all at once, like so: "The first row\n" "My second row\n" "This is the last row\n" The translators will also get this complete blurb marked for translation in its entirety as well. This approach has several drawbacks for translation. Often, the options in a combobox are very much standalone option strings that don't bring much extra context when grouped together. Instead, the grouping brings important disadvantages: * Fragility from reordering. Whenever the developer decides to re-order the options in the combobox, all translations will need updating. * Makes changes unvisible. Comboboxes are quite often big and hold many rows. This makes for huge messages with many rows. Spotting changes in such big lists is a pain when updating a translation. A row-based approach, where the rows are marked for translation seperately and added one by one, would be much better in this respect.
For the generated code Glade does output each string separately. So the problem is with the XML file or libglade and intltool. Maybe instead of outputting all items together in the XML file we should use a repeated element, e.g. instead of: <property name="items" translatable="yes">first item second item third item</property> we output: <property name="item" translatable="yes">first item</property> <property name="item" translatable="yes">second item</property> <property name="item" translatable="yes">third item</property> For long lists it will get a lot bigger though. And I'm not sure if repeated properties are OK. I'll move this to libglade since it needs to be supported there first, if we are going to change it.
If libglade actually calls *gettext family of functions on one item at a time (i.e. it would call gettext("first item"), and not gettext("first item\nsecond item\n...")), then we might add support to intltool-extract to handle this properly, if that's easier for you (no breaking of backwards compatibility). Actually, intltool-extract seems to have handled this for "old style Glade files": while ($input =~ /<items>(..[^<]*)<\/items>/sg) { for my $item (split (/\n/, $1)) { $messages{entity_decode($item)} = []; } } If you wish us to simply add support for this in intltool instead of changing libglade, move this bug there, and I'll work on updating it. It should be simple enough, because one regex would have to be changed: while ($input =~ /<(property|atkproperty)\s+[^>]*translatable\s*=\s*"yes"(?: \s+[^>]*comments\s*=\s*"([^"]*)")?[^>]*>([^<]+)<\/\1>/sg) { We'd have to extract property "name" here as well, and check if it's "items". Still, regexes are getting increasingly ugly in intltool-extract, and I hope to switch it all to proper XML parser in the near future.
That does break backwards compatability though, i.e. apps that were built with the old intltool will have all items in one string, and the new libglade would split the string, so the items wouldn't get translated. It also relies on a bit of special knowledge of the "items" properties, which I don't really like. The repeated "item" property is cleaner, and explicit. Though it would be nice to have a way to set the rows of list models anyway, so maybe we should wait until that is available.
I was under the impression that compatibility was broken earlier, i.e. when the change from oldstyle Glade files to new was done. That's how I understood Christian's remark that this may not actually work currently with libglade. I don't have the time right now to look into libglade source code, so I'll trust you on this one :) Of course, even if that's the case, intltool will require updates, but lets discuss that once you settle on the format for .glade files.
In the old 0.x releases of libglade and 1.x releases of glade, there was special support for the <items> element in glade files. It would split the element content by lines before translating it. In the current version of glade, the gettext() calls are done while the glade file is being parsed, which is before it has even applied any special meaning to properties. Instead, it relys on strings to be explicitly marked for translation. If we wanted to support the "split by lines then translate" behaviour, I'd prefer to do it by adding a new value for the "translatable" attribute. However, a change of this type would cause problems with mismatches between the version of libglade used, and the version of intltool used to generate the .pot file. Now, the alternative is for the glade file to list the items explicitly. It would look something like this (some elements and attributes omitted): <widget class="GtkCombo"> <child internal-child="list"> <widget class="GtkList"> <child> <widget class="GtkListItem"> <property name="label" translatable="yes">Item 1</property> </widget> </child> <child> <widget class="GtkListItem"> <property name="label" translatable="yes">Item 2</property> </widget> </child> ... </widget> </child> </widget> Unless I'm mistaken, the above should work for all libglade-2.x releases.
That works for GtkCombo, but not for the newer GtkComboBox/GtkComboBoxEntry widgets, which use a GtkTreeModel. Using 'translatable="lines"' sounds like a reasonable & simple hack.
The GNOME Release team has officially deprecated libglade in favor of GtkBuilder[1]. So it's unlikely to get further development. I am closing bugs as WONTFIX. Please feel free to reopen the bugs in future if anyone takes the responsibility for active development. [1] http://permalink.gmane.org/gmane.comp.gnome.devel.announce/28