Patchwork [7/9] gtk: add translation support (v5)

login
register
mail settings
Submitter Anthony Liguori
Date Feb. 20, 2013, 1:43 p.m.
Message ID <1361367806-4599-8-git-send-email-aliguori@us.ibm.com>
Download mbox | patch
Permalink /patch/222100/
State New
Headers show

Comments

Anthony Liguori - Feb. 20, 2013, 1:43 p.m.
This includes a de_DE translation from Kevin Wolf and an it translation from
Paolo Bonzini.

Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Kevin Wolf <kwolf@redhat.com>
Cc: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
v1 -> v4
 - Don't use '|| exit 1' with sub-invocation of make
 - Actually include Kevin's translation
v4 -> v5
 - Update translations (Kevin and Paolo)
 - Fix 'make update' for it.po
---
 Makefile       |  3 +++
 configure      |  4 +++-
 po/Makefile    | 46 ++++++++++++++++++++++++++++++++++++++++++++++
 po/de_DE.po    | 45 +++++++++++++++++++++++++++++++++++++++++++++
 po/it.po       | 45 +++++++++++++++++++++++++++++++++++++++++++++
 po/messages.po | 45 +++++++++++++++++++++++++++++++++++++++++++++
 ui/gtk.c       | 22 +++++++++++++++-------
 7 files changed, 202 insertions(+), 8 deletions(-)
 create mode 100644 po/Makefile
 create mode 100644 po/de_DE.po
 create mode 100644 po/it.po
 create mode 100644 po/messages.po
Andreas Färber - Feb. 20, 2013, 4:10 p.m.
Am 20.02.2013 14:43, schrieb Anthony Liguori:
> This includes a de_DE translation from Kevin Wolf and an it translation from
> Paolo Bonzini.
> 
> Cc: Paolo Bonzini <pbonzini@redhat.com>
> Cc: Kevin Wolf <kwolf@redhat.com>
> Cc: Stefan Hajnoczi <stefanha@redhat.com>
> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
> ---
> v1 -> v4
>  - Don't use '|| exit 1' with sub-invocation of make
>  - Actually include Kevin's translation
> v4 -> v5
>  - Update translations (Kevin and Paolo)
>  - Fix 'make update' for it.po
> ---
>  Makefile       |  3 +++
>  configure      |  4 +++-
>  po/Makefile    | 46 ++++++++++++++++++++++++++++++++++++++++++++++
>  po/de_DE.po    | 45 +++++++++++++++++++++++++++++++++++++++++++++
>  po/it.po       | 45 +++++++++++++++++++++++++++++++++++++++++++++
>  po/messages.po | 45 +++++++++++++++++++++++++++++++++++++++++++++
>  ui/gtk.c       | 22 +++++++++++++++-------
>  7 files changed, 202 insertions(+), 8 deletions(-)
>  create mode 100644 po/Makefile
>  create mode 100644 po/de_DE.po
>  create mode 100644 po/it.po
>  create mode 100644 po/messages.po

IIUC this uses the English texts as key for lookup of translations.
Experience shows that while that is most convenient for the English it
leads to grammatical mistakes in other languages due to text reuse in
wrong contexts. A prominent example is "Server" being translated as
"Kellner" (which is waiter) in some early Windows NT version. :) More
recent examples commonly found are ambiguities of, e.g., "Update" as
noun vs. imperative - happens if the same wording is used in a menu and
in some options dialog or status text. Similar for ing-forms translated
as noun vs. infinitive vs. first-person present.

Better would be to use unique alphanumeric identifiers (e.g.,
"Menu.File.Quit") and to have a regular translation file for en (or
whatever suitable as fallback).

Regards,
Andreas
Daniel P. Berrange - Feb. 20, 2013, 4:16 p.m.
On Wed, Feb 20, 2013 at 05:10:54PM +0100, Andreas Färber wrote:
> Am 20.02.2013 14:43, schrieb Anthony Liguori:
> > This includes a de_DE translation from Kevin Wolf and an it translation from
> > Paolo Bonzini.
> > 
> > Cc: Paolo Bonzini <pbonzini@redhat.com>
> > Cc: Kevin Wolf <kwolf@redhat.com>
> > Cc: Stefan Hajnoczi <stefanha@redhat.com>
> > Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
> > ---
> > v1 -> v4
> >  - Don't use '|| exit 1' with sub-invocation of make
> >  - Actually include Kevin's translation
> > v4 -> v5
> >  - Update translations (Kevin and Paolo)
> >  - Fix 'make update' for it.po
> > ---
> >  Makefile       |  3 +++
> >  configure      |  4 +++-
> >  po/Makefile    | 46 ++++++++++++++++++++++++++++++++++++++++++++++
> >  po/de_DE.po    | 45 +++++++++++++++++++++++++++++++++++++++++++++
> >  po/it.po       | 45 +++++++++++++++++++++++++++++++++++++++++++++
> >  po/messages.po | 45 +++++++++++++++++++++++++++++++++++++++++++++
> >  ui/gtk.c       | 22 +++++++++++++++-------
> >  7 files changed, 202 insertions(+), 8 deletions(-)
> >  create mode 100644 po/Makefile
> >  create mode 100644 po/de_DE.po
> >  create mode 100644 po/it.po
> >  create mode 100644 po/messages.po
> 
> IIUC this uses the English texts as key for lookup of translations.
> Experience shows that while that is most convenient for the English it
> leads to grammatical mistakes in other languages due to text reuse in
> wrong contexts. A prominent example is "Server" being translated as
> "Kellner" (which is waiter) in some early Windows NT version. :) More
> recent examples commonly found are ambiguities of, e.g., "Update" as
> noun vs. imperative - happens if the same wording is used in a menu and
> in some options dialog or status text. Similar for ing-forms translated
> as noun vs. infinitive vs. first-person present.
> 
> Better would be to use unique alphanumeric identifiers (e.g.,
> "Menu.File.Quit") and to have a regular translation file for en (or
> whatever suitable as fallback).

Your points may be valid, but this patch follows standard practice for
i18n of any GTK app, in fact standard across pretty much all open
source projects I've worked on. I don't think QEMU should try to do
something non-standard for translation files.

Daniel
Andreas Färber - Feb. 20, 2013, 4:24 p.m.
Am 20.02.2013 17:16, schrieb Daniel P. Berrange:
> On Wed, Feb 20, 2013 at 05:10:54PM +0100, Andreas Färber wrote:
>> Am 20.02.2013 14:43, schrieb Anthony Liguori:
>>> This includes a de_DE translation from Kevin Wolf and an it translation from
>>> Paolo Bonzini.
>>>
>>> Cc: Paolo Bonzini <pbonzini@redhat.com>
>>> Cc: Kevin Wolf <kwolf@redhat.com>
>>> Cc: Stefan Hajnoczi <stefanha@redhat.com>
>>> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
>>> ---
>>> v1 -> v4
>>>  - Don't use '|| exit 1' with sub-invocation of make
>>>  - Actually include Kevin's translation
>>> v4 -> v5
>>>  - Update translations (Kevin and Paolo)
>>>  - Fix 'make update' for it.po
>>> ---
>>>  Makefile       |  3 +++
>>>  configure      |  4 +++-
>>>  po/Makefile    | 46 ++++++++++++++++++++++++++++++++++++++++++++++
>>>  po/de_DE.po    | 45 +++++++++++++++++++++++++++++++++++++++++++++
>>>  po/it.po       | 45 +++++++++++++++++++++++++++++++++++++++++++++
>>>  po/messages.po | 45 +++++++++++++++++++++++++++++++++++++++++++++
>>>  ui/gtk.c       | 22 +++++++++++++++-------
>>>  7 files changed, 202 insertions(+), 8 deletions(-)
>>>  create mode 100644 po/Makefile
>>>  create mode 100644 po/de_DE.po
>>>  create mode 100644 po/it.po
>>>  create mode 100644 po/messages.po
>>
>> IIUC this uses the English texts as key for lookup of translations.
>> Experience shows that while that is most convenient for the English it
>> leads to grammatical mistakes in other languages due to text reuse in
>> wrong contexts. A prominent example is "Server" being translated as
>> "Kellner" (which is waiter) in some early Windows NT version. :) More
>> recent examples commonly found are ambiguities of, e.g., "Update" as
>> noun vs. imperative - happens if the same wording is used in a menu and
>> in some options dialog or status text. Similar for ing-forms translated
>> as noun vs. infinitive vs. first-person present.
>>
>> Better would be to use unique alphanumeric identifiers (e.g.,
>> "Menu.File.Quit") and to have a regular translation file for en (or
>> whatever suitable as fallback).
> 
> Your points may be valid, but this patch follows standard practice for
> i18n of any GTK app, in fact standard across pretty much all open
> source projects I've worked on. I don't think QEMU should try to do
> something non-standard for translation files.

Not having translations may be better quality-wise than having known
broken translations just because that is considered standard practice by
English speakers that don't actually see or need them.

Andreas
Daniel P. Berrange - Feb. 20, 2013, 4:53 p.m.
On Wed, Feb 20, 2013 at 05:24:02PM +0100, Andreas Färber wrote:
> Am 20.02.2013 17:16, schrieb Daniel P. Berrange:
> > On Wed, Feb 20, 2013 at 05:10:54PM +0100, Andreas Färber wrote:
> >> Am 20.02.2013 14:43, schrieb Anthony Liguori:
> >>> This includes a de_DE translation from Kevin Wolf and an it translation from
> >>> Paolo Bonzini.
> >>>
> >>> Cc: Paolo Bonzini <pbonzini@redhat.com>
> >>> Cc: Kevin Wolf <kwolf@redhat.com>
> >>> Cc: Stefan Hajnoczi <stefanha@redhat.com>
> >>> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
> >>> ---
> >>> v1 -> v4
> >>>  - Don't use '|| exit 1' with sub-invocation of make
> >>>  - Actually include Kevin's translation
> >>> v4 -> v5
> >>>  - Update translations (Kevin and Paolo)
> >>>  - Fix 'make update' for it.po
> >>> ---
> >>>  Makefile       |  3 +++
> >>>  configure      |  4 +++-
> >>>  po/Makefile    | 46 ++++++++++++++++++++++++++++++++++++++++++++++
> >>>  po/de_DE.po    | 45 +++++++++++++++++++++++++++++++++++++++++++++
> >>>  po/it.po       | 45 +++++++++++++++++++++++++++++++++++++++++++++
> >>>  po/messages.po | 45 +++++++++++++++++++++++++++++++++++++++++++++
> >>>  ui/gtk.c       | 22 +++++++++++++++-------
> >>>  7 files changed, 202 insertions(+), 8 deletions(-)
> >>>  create mode 100644 po/Makefile
> >>>  create mode 100644 po/de_DE.po
> >>>  create mode 100644 po/it.po
> >>>  create mode 100644 po/messages.po
> >>
> >> IIUC this uses the English texts as key for lookup of translations.
> >> Experience shows that while that is most convenient for the English it
> >> leads to grammatical mistakes in other languages due to text reuse in
> >> wrong contexts. A prominent example is "Server" being translated as
> >> "Kellner" (which is waiter) in some early Windows NT version. :) More
> >> recent examples commonly found are ambiguities of, e.g., "Update" as
> >> noun vs. imperative - happens if the same wording is used in a menu and
> >> in some options dialog or status text. Similar for ing-forms translated
> >> as noun vs. infinitive vs. first-person present.
> >>
> >> Better would be to use unique alphanumeric identifiers (e.g.,
> >> "Menu.File.Quit") and to have a regular translation file for en (or
> >> whatever suitable as fallback).
> > 
> > Your points may be valid, but this patch follows standard practice for
> > i18n of any GTK app, in fact standard across pretty much all open
> > source projects I've worked on. I don't think QEMU should try to do
> > something non-standard for translation files.
> 
> Not having translations may be better quality-wise than having known
> broken translations just because that is considered standard practice by
> English speakers that don't actually see or need them.

People doing the translations simply need to be aware of the issue and
look at the context of the usage. Developes can help them do this by
putting special comments in the source code to provide hints on context
eg

  /* TRANSLATORS: ....some hint texts.... */
  foo(_("Some string"))

this text gets copied into the .pot file

  #. TRANSLATORS: ...some hint texts...
  #: filename.c
  msgid "Some string"
  msgstr ""

so the translators can then understand the usage context & do the right
translation.

Daniel
Anthony Liguori - Feb. 20, 2013, 5:05 p.m.
Andreas Färber <afaerber@suse.de> writes:

> Am 20.02.2013 14:43, schrieb Anthony Liguori:
>> This includes a de_DE translation from Kevin Wolf and an it translation from
>> Paolo Bonzini.
>> 
>> Cc: Paolo Bonzini <pbonzini@redhat.com>
>> Cc: Kevin Wolf <kwolf@redhat.com>
>> Cc: Stefan Hajnoczi <stefanha@redhat.com>
>> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
>> ---
>> v1 -> v4
>>  - Don't use '|| exit 1' with sub-invocation of make
>>  - Actually include Kevin's translation
>> v4 -> v5
>>  - Update translations (Kevin and Paolo)
>>  - Fix 'make update' for it.po
>> ---
>>  Makefile       |  3 +++
>>  configure      |  4 +++-
>>  po/Makefile    | 46 ++++++++++++++++++++++++++++++++++++++++++++++
>>  po/de_DE.po    | 45 +++++++++++++++++++++++++++++++++++++++++++++
>>  po/it.po       | 45 +++++++++++++++++++++++++++++++++++++++++++++
>>  po/messages.po | 45 +++++++++++++++++++++++++++++++++++++++++++++
>>  ui/gtk.c       | 22 +++++++++++++++-------
>>  7 files changed, 202 insertions(+), 8 deletions(-)
>>  create mode 100644 po/Makefile
>>  create mode 100644 po/de_DE.po
>>  create mode 100644 po/it.po
>>  create mode 100644 po/messages.po
>
> IIUC this uses the English texts as key for lookup of translations.
> Experience shows that while that is most convenient for the English it
> leads to grammatical mistakes in other languages due to text reuse in
> wrong contexts. A prominent example is "Server" being translated as
> "Kellner" (which is waiter) in some early Windows NT version. :) More
> recent examples commonly found are ambiguities of, e.g., "Update" as
> noun vs. imperative - happens if the same wording is used in a menu and
> in some options dialog or status text. Similar for ing-forms translated
> as noun vs. infinitive vs. first-person present.

Right or wrong, this is how GTK apps are written.  If you disagree with
it, take it up with the Gnome folks.  Consistency trumps "rightness"
here.

Regards,

Anthony Liguori

>
> Better would be to use unique alphanumeric identifiers (e.g.,
> "Menu.File.Quit") and to have a regular translation file for en (or
> whatever suitable as fallback).
>
> Regards,
> Andreas
>
> -- 
> SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
> GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
Andreas Färber - Feb. 20, 2013, 5:19 p.m.
Am 20.02.2013 17:53, schrieb Daniel P. Berrange:
> On Wed, Feb 20, 2013 at 05:24:02PM +0100, Andreas Färber wrote:
>> Am 20.02.2013 17:16, schrieb Daniel P. Berrange:
>>> On Wed, Feb 20, 2013 at 05:10:54PM +0100, Andreas Färber wrote:
>>>> Am 20.02.2013 14:43, schrieb Anthony Liguori:
>>>>> This includes a de_DE translation from Kevin Wolf and an it translation from
>>>>> Paolo Bonzini.
>>>>>
>>>>> Cc: Paolo Bonzini <pbonzini@redhat.com>
>>>>> Cc: Kevin Wolf <kwolf@redhat.com>
>>>>> Cc: Stefan Hajnoczi <stefanha@redhat.com>
>>>>> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
>>>>> ---
>>>>> v1 -> v4
>>>>>  - Don't use '|| exit 1' with sub-invocation of make
>>>>>  - Actually include Kevin's translation
>>>>> v4 -> v5
>>>>>  - Update translations (Kevin and Paolo)
>>>>>  - Fix 'make update' for it.po
>>>>> ---
>>>>>  Makefile       |  3 +++
>>>>>  configure      |  4 +++-
>>>>>  po/Makefile    | 46 ++++++++++++++++++++++++++++++++++++++++++++++
>>>>>  po/de_DE.po    | 45 +++++++++++++++++++++++++++++++++++++++++++++
>>>>>  po/it.po       | 45 +++++++++++++++++++++++++++++++++++++++++++++
>>>>>  po/messages.po | 45 +++++++++++++++++++++++++++++++++++++++++++++
>>>>>  ui/gtk.c       | 22 +++++++++++++++-------
>>>>>  7 files changed, 202 insertions(+), 8 deletions(-)
>>>>>  create mode 100644 po/Makefile
>>>>>  create mode 100644 po/de_DE.po
>>>>>  create mode 100644 po/it.po
>>>>>  create mode 100644 po/messages.po
>>>>
>>>> IIUC this uses the English texts as key for lookup of translations.
>>>> Experience shows that while that is most convenient for the English it
>>>> leads to grammatical mistakes in other languages due to text reuse in
>>>> wrong contexts. A prominent example is "Server" being translated as
>>>> "Kellner" (which is waiter) in some early Windows NT version. :) More
>>>> recent examples commonly found are ambiguities of, e.g., "Update" as
>>>> noun vs. imperative - happens if the same wording is used in a menu and
>>>> in some options dialog or status text. Similar for ing-forms translated
>>>> as noun vs. infinitive vs. first-person present.
>>>>
>>>> Better would be to use unique alphanumeric identifiers (e.g.,
>>>> "Menu.File.Quit") and to have a regular translation file for en (or
>>>> whatever suitable as fallback).
>>>
>>> Your points may be valid, but this patch follows standard practice for
>>> i18n of any GTK app, in fact standard across pretty much all open
>>> source projects I've worked on. I don't think QEMU should try to do
>>> something non-standard for translation files.
>>
>> Not having translations may be better quality-wise than having known
>> broken translations just because that is considered standard practice by
>> English speakers that don't actually see or need them.
> 
> People doing the translations simply need to be aware of the issue and
> look at the context of the usage. Developes can help them do this by
> putting special comments in the source code to provide hints on context
> eg
> 
>   /* TRANSLATORS: ....some hint texts.... */
>   foo(_("Some string"))
> 
> this text gets copied into the .pot file
> 
>   #. TRANSLATORS: ...some hint texts...
>   #: filename.c
>   msgid "Some string"
>   msgstr ""
> 
> so the translators can then understand the usage context & do the right
> translation.

You're missing my point: The problem is the msgid "Foo" line unless you
get msgid "Foo" for each occurrence of _L("Foo") rather than once. If
the tools allow per-occurrence translations then everything is fine,
with or without comments. Problem is only when tools try to be clever.

Andreas
Andreas Färber - Feb. 20, 2013, 5:26 p.m.
Am 20.02.2013 18:05, schrieb Anthony Liguori:
> Andreas Färber <afaerber@suse.de> writes:
> 
>> Am 20.02.2013 14:43, schrieb Anthony Liguori:
>>> This includes a de_DE translation from Kevin Wolf and an it translation from
>>> Paolo Bonzini.
>>>
>>> Cc: Paolo Bonzini <pbonzini@redhat.com>
>>> Cc: Kevin Wolf <kwolf@redhat.com>
>>> Cc: Stefan Hajnoczi <stefanha@redhat.com>
>>> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
>>> ---
>>> v1 -> v4
>>>  - Don't use '|| exit 1' with sub-invocation of make
>>>  - Actually include Kevin's translation
>>> v4 -> v5
>>>  - Update translations (Kevin and Paolo)
>>>  - Fix 'make update' for it.po
>>> ---
>>>  Makefile       |  3 +++
>>>  configure      |  4 +++-
>>>  po/Makefile    | 46 ++++++++++++++++++++++++++++++++++++++++++++++
>>>  po/de_DE.po    | 45 +++++++++++++++++++++++++++++++++++++++++++++
>>>  po/it.po       | 45 +++++++++++++++++++++++++++++++++++++++++++++
>>>  po/messages.po | 45 +++++++++++++++++++++++++++++++++++++++++++++
>>>  ui/gtk.c       | 22 +++++++++++++++-------
>>>  7 files changed, 202 insertions(+), 8 deletions(-)
>>>  create mode 100644 po/Makefile
>>>  create mode 100644 po/de_DE.po
>>>  create mode 100644 po/it.po
>>>  create mode 100644 po/messages.po
>>
>> IIUC this uses the English texts as key for lookup of translations.
>> Experience shows that while that is most convenient for the English it
>> leads to grammatical mistakes in other languages due to text reuse in
>> wrong contexts. A prominent example is "Server" being translated as
>> "Kellner" (which is waiter) in some early Windows NT version. :) More
>> recent examples commonly found are ambiguities of, e.g., "Update" as
>> noun vs. imperative - happens if the same wording is used in a menu and
>> in some options dialog or status text. Similar for ing-forms translated
>> as noun vs. infinitive vs. first-person present.
> 
> Right or wrong, this is how GTK apps are written.  If you disagree with
> it, take it up with the Gnome folks.  Consistency trumps "rightness"
> here.

You don't translate error_setg() et al., so translating a few UI items
is in fact inconsistent here.

GNOME folks also use GNU autoconf and different Coding Style.

A more critical issue would be distro packaging though.
An alternative idea would be to separate the _L() text from the English
text if that is possible through some macro, cmp. reply to Daniel.

Regards,
Andreas
Daniel P. Berrange - Feb. 20, 2013, 5:28 p.m.
On Wed, Feb 20, 2013 at 06:19:49PM +0100, Andreas Färber wrote:
> Am 20.02.2013 17:53, schrieb Daniel P. Berrange:
> > On Wed, Feb 20, 2013 at 05:24:02PM +0100, Andreas Färber wrote:
> >> Am 20.02.2013 17:16, schrieb Daniel P. Berrange:
> >>> On Wed, Feb 20, 2013 at 05:10:54PM +0100, Andreas Färber wrote:
> >>>> Am 20.02.2013 14:43, schrieb Anthony Liguori:
> >>>>> This includes a de_DE translation from Kevin Wolf and an it translation from
> >>>>> Paolo Bonzini.
> >>>>>
> >>>>> Cc: Paolo Bonzini <pbonzini@redhat.com>
> >>>>> Cc: Kevin Wolf <kwolf@redhat.com>
> >>>>> Cc: Stefan Hajnoczi <stefanha@redhat.com>
> >>>>> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
> >>>>> ---
> >>>>> v1 -> v4
> >>>>>  - Don't use '|| exit 1' with sub-invocation of make
> >>>>>  - Actually include Kevin's translation
> >>>>> v4 -> v5
> >>>>>  - Update translations (Kevin and Paolo)
> >>>>>  - Fix 'make update' for it.po
> >>>>> ---
> >>>>>  Makefile       |  3 +++
> >>>>>  configure      |  4 +++-
> >>>>>  po/Makefile    | 46 ++++++++++++++++++++++++++++++++++++++++++++++
> >>>>>  po/de_DE.po    | 45 +++++++++++++++++++++++++++++++++++++++++++++
> >>>>>  po/it.po       | 45 +++++++++++++++++++++++++++++++++++++++++++++
> >>>>>  po/messages.po | 45 +++++++++++++++++++++++++++++++++++++++++++++
> >>>>>  ui/gtk.c       | 22 +++++++++++++++-------
> >>>>>  7 files changed, 202 insertions(+), 8 deletions(-)
> >>>>>  create mode 100644 po/Makefile
> >>>>>  create mode 100644 po/de_DE.po
> >>>>>  create mode 100644 po/it.po
> >>>>>  create mode 100644 po/messages.po
> >>>>
> >>>> IIUC this uses the English texts as key for lookup of translations.
> >>>> Experience shows that while that is most convenient for the English it
> >>>> leads to grammatical mistakes in other languages due to text reuse in
> >>>> wrong contexts. A prominent example is "Server" being translated as
> >>>> "Kellner" (which is waiter) in some early Windows NT version. :) More
> >>>> recent examples commonly found are ambiguities of, e.g., "Update" as
> >>>> noun vs. imperative - happens if the same wording is used in a menu and
> >>>> in some options dialog or status text. Similar for ing-forms translated
> >>>> as noun vs. infinitive vs. first-person present.
> >>>>
> >>>> Better would be to use unique alphanumeric identifiers (e.g.,
> >>>> "Menu.File.Quit") and to have a regular translation file for en (or
> >>>> whatever suitable as fallback).
> >>>
> >>> Your points may be valid, but this patch follows standard practice for
> >>> i18n of any GTK app, in fact standard across pretty much all open
> >>> source projects I've worked on. I don't think QEMU should try to do
> >>> something non-standard for translation files.
> >>
> >> Not having translations may be better quality-wise than having known
> >> broken translations just because that is considered standard practice by
> >> English speakers that don't actually see or need them.
> > 
> > People doing the translations simply need to be aware of the issue and
> > look at the context of the usage. Developes can help them do this by
> > putting special comments in the source code to provide hints on context
> > eg
> > 
> >   /* TRANSLATORS: ....some hint texts.... */
> >   foo(_("Some string"))
> > 
> > this text gets copied into the .pot file
> > 
> >   #. TRANSLATORS: ...some hint texts...
> >   #: filename.c
> >   msgid "Some string"
> >   msgstr ""
> > 
> > so the translators can then understand the usage context & do the right
> > translation.
> 
> You're missing my point: The problem is the msgid "Foo" line unless you
> get msgid "Foo" for each occurrence of _L("Foo") rather than once. If
> the tools allow per-occurrence translations then everything is fine,
> with or without comments. Problem is only when tools try to be clever.

That problem is solveable too:

 https://www.gnu.org/software/gettext/manual/gettext.html#Contexts

Regards,
Daniel
Kevin Wolf - Feb. 21, 2013, 8:38 a.m.
On Wed, Feb 20, 2013 at 06:26:55PM +0100, Andreas Färber wrote:
> Am 20.02.2013 18:05, schrieb Anthony Liguori:
> > Andreas Färber <afaerber@suse.de> writes:
> > 
> >> Am 20.02.2013 14:43, schrieb Anthony Liguori:
> >>> This includes a de_DE translation from Kevin Wolf and an it translation from
> >>> Paolo Bonzini.
> >>>
> >>> Cc: Paolo Bonzini <pbonzini@redhat.com>
> >>> Cc: Kevin Wolf <kwolf@redhat.com>
> >>> Cc: Stefan Hajnoczi <stefanha@redhat.com>
> >>> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
> >>> ---
> >>> v1 -> v4
> >>>  - Don't use '|| exit 1' with sub-invocation of make
> >>>  - Actually include Kevin's translation
> >>> v4 -> v5
> >>>  - Update translations (Kevin and Paolo)
> >>>  - Fix 'make update' for it.po
> >>> ---
> >>>  Makefile       |  3 +++
> >>>  configure      |  4 +++-
> >>>  po/Makefile    | 46 ++++++++++++++++++++++++++++++++++++++++++++++
> >>>  po/de_DE.po    | 45 +++++++++++++++++++++++++++++++++++++++++++++
> >>>  po/it.po       | 45 +++++++++++++++++++++++++++++++++++++++++++++
> >>>  po/messages.po | 45 +++++++++++++++++++++++++++++++++++++++++++++
> >>>  ui/gtk.c       | 22 +++++++++++++++-------
> >>>  7 files changed, 202 insertions(+), 8 deletions(-)
> >>>  create mode 100644 po/Makefile
> >>>  create mode 100644 po/de_DE.po
> >>>  create mode 100644 po/it.po
> >>>  create mode 100644 po/messages.po
> >>
> >> IIUC this uses the English texts as key for lookup of translations.
> >> Experience shows that while that is most convenient for the English it
> >> leads to grammatical mistakes in other languages due to text reuse in
> >> wrong contexts. A prominent example is "Server" being translated as
> >> "Kellner" (which is waiter) in some early Windows NT version. :) More
> >> recent examples commonly found are ambiguities of, e.g., "Update" as
> >> noun vs. imperative - happens if the same wording is used in a menu and
> >> in some options dialog or status text. Similar for ing-forms translated
> >> as noun vs. infinitive vs. first-person present.
> > 
> > Right or wrong, this is how GTK apps are written.  If you disagree with
> > it, take it up with the Gnome folks.  Consistency trumps "rightness"
> > here.
> 
> You don't translate error_setg() et al., so translating a few UI items
> is in fact inconsistent here.

I think the plan with error messages was to have them translated
eventually, which is one of the reasons why clients may not parse them
(and strerror() results are already translated today).

But since we're using some standard GTK menu entries, not translating
would actually give you the much bigger inconsistency: In the same menu,
you would have both English and translated entries. This is what the
first version of this patch series had, and which I really hated.

As long as there is a logical separation between translated and
untranslated strings (e.g. menus are translated, the monitor is English)
I don't see a problem with it.

> A more critical issue would be distro packaging though.
> An alternative idea would be to separate the _L() text from the English
> text if that is possible through some macro, cmp. reply to Daniel.

You want qemu to be usable with LANG=C, so using identifiers instead of
English texts doesn't really work. The gettext functions that allow
specifying a context look like a better solution to solve the problem
if it ever comes up.

Kevin
Andreas Färber - Feb. 22, 2013, 5:50 p.m.
Am 21.02.2013 09:38, schrieb Kevin Wolf:
> On Wed, Feb 20, 2013 at 06:26:55PM +0100, Andreas Färber wrote:
>> Am 20.02.2013 18:05, schrieb Anthony Liguori:
>>> Andreas Färber <afaerber@suse.de> writes:
>>>
>>>> Am 20.02.2013 14:43, schrieb Anthony Liguori:
>>>>> This includes a de_DE translation from Kevin Wolf and an it translation from
>>>>> Paolo Bonzini.
>>>>>
>>>>> Cc: Paolo Bonzini <pbonzini@redhat.com>
>>>>> Cc: Kevin Wolf <kwolf@redhat.com>
>>>>> Cc: Stefan Hajnoczi <stefanha@redhat.com>
>>>>> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
>>>>> ---
>>>>> v1 -> v4
>>>>>  - Don't use '|| exit 1' with sub-invocation of make
>>>>>  - Actually include Kevin's translation
>>>>> v4 -> v5
>>>>>  - Update translations (Kevin and Paolo)
>>>>>  - Fix 'make update' for it.po
>>>>> ---
>>>>>  Makefile       |  3 +++
>>>>>  configure      |  4 +++-
>>>>>  po/Makefile    | 46 ++++++++++++++++++++++++++++++++++++++++++++++
>>>>>  po/de_DE.po    | 45 +++++++++++++++++++++++++++++++++++++++++++++
>>>>>  po/it.po       | 45 +++++++++++++++++++++++++++++++++++++++++++++
>>>>>  po/messages.po | 45 +++++++++++++++++++++++++++++++++++++++++++++
>>>>>  ui/gtk.c       | 22 +++++++++++++++-------
>>>>>  7 files changed, 202 insertions(+), 8 deletions(-)
>>>>>  create mode 100644 po/Makefile
>>>>>  create mode 100644 po/de_DE.po
>>>>>  create mode 100644 po/it.po
>>>>>  create mode 100644 po/messages.po
>>>>
>>>> IIUC this uses the English texts as key for lookup of translations.
>>>> Experience shows that while that is most convenient for the English it
>>>> leads to grammatical mistakes in other languages due to text reuse in
>>>> wrong contexts. A prominent example is "Server" being translated as
>>>> "Kellner" (which is waiter) in some early Windows NT version. :) More
>>>> recent examples commonly found are ambiguities of, e.g., "Update" as
>>>> noun vs. imperative - happens if the same wording is used in a menu and
>>>> in some options dialog or status text. Similar for ing-forms translated
>>>> as noun vs. infinitive vs. first-person present.
>>>
>>> Right or wrong, this is how GTK apps are written.  If you disagree with
>>> it, take it up with the Gnome folks.  Consistency trumps "rightness"
>>> here.
>>
>> You don't translate error_setg() et al., so translating a few UI items
>> is in fact inconsistent here.
> 
> I think the plan with error messages was to have them translated
> eventually, which is one of the reasons why clients may not parse them
> (and strerror() results are already translated today).
> 
> But since we're using some standard GTK menu entries, not translating
> would actually give you the much bigger inconsistency: In the same menu,
> you would have both English and translated entries. This is what the
> first version of this patch series had, and which I really hated.

I agree that a mix of English and German is bad.

Unfortunately that is exactly what I see on my German system now
*despite* translation support (v5) being committed!

Andreas

> 
> As long as there is a logical separation between translated and
> untranslated strings (e.g. menus are translated, the monitor is English)
> I don't see a problem with it.
> 
>> A more critical issue would be distro packaging though.
>> An alternative idea would be to separate the _L() text from the English
>> text if that is possible through some macro, cmp. reply to Daniel.
> 
> You want qemu to be usable with LANG=C, so using identifiers instead of
> English texts doesn't really work. The gettext functions that allow
> specifying a context look like a better solution to solve the problem
> if it ever comes up.
> 
> Kevin
>
Paolo Bonzini - Feb. 22, 2013, 5:51 p.m.
Il 22/02/2013 18:50, Andreas Färber ha scritto:
>> > But since we're using some standard GTK menu entries, not translating
>> > would actually give you the much bigger inconsistency: In the same menu,
>> > you would have both English and translated entries. This is what the
>> > first version of this patch series had, and which I really hated.
> I agree that a mix of English and German is bad.
> 
> Unfortunately that is exactly what I see on my German system now
> *despite* translation support (v5) being committed!

Did you install the .gmo file to /usr?

Paolo
Andreas Färber - Feb. 22, 2013, 5:57 p.m.
Am 22.02.2013 18:51, schrieb Paolo Bonzini:
> Il 22/02/2013 18:50, Andreas Färber ha scritto:
>>>> But since we're using some standard GTK menu entries, not translating
>>>> would actually give you the much bigger inconsistency: In the same menu,
>>>> you would have both English and translated entries. This is what the
>>>> first version of this patch series had, and which I really hated.
>> I agree that a mix of English and German is bad.
>>
>> Unfortunately that is exactly what I see on my German system now
>> *despite* translation support (v5) being committed!
> 
> Did you install the .gmo file to /usr?

No, as a developer I execute ./x86_64-softmmu/qemu-system-x86_64 and
have the openSUSE version in /usr and the stable version in /usr/local.

Shouldn't QEMU set paths up so that it works just like -L?

Andreas
Stefan Weil - Feb. 22, 2013, 6:05 p.m.
Am 22.02.2013 18:51, schrieb Paolo Bonzini:
> Il 22/02/2013 18:50, Andreas Färber ha scritto:
>>>> But since we're using some standard GTK menu entries, not translating
>>>> would actually give you the much bigger inconsistency: In the same menu,
>>>> you would have both English and translated entries. This is what the
>>>> first version of this patch series had, and which I really hated.
>> I agree that a mix of English and German is bad.
>>
>> Unfortunately that is exactly what I see on my German system now
>> *despite* translation support (v5) being committed!
> Did you install the .gmo file to /usr?
>
> Paolo

The current implementation requires that .mo / .gmofiles are installed.
Those files are only built with "make install", but not with the default
"make all".

That's ok for distributions but does not match my personal practice.
I nearly never install, but usually call the executables from by build tree
(with -L pc-bios).

As I want to continue working like that, some Makefile modifications
would be nice.

Stefan

PS. I noticed "public domain" in the .po files and remembered some
recent not so nice discussion about license issues.
Kevin, Paolo,maybe you find a better license clause?
Anthony Liguori - Feb. 22, 2013, 7:08 p.m.
Andreas Färber <afaerber@suse.de> writes:

> Am 21.02.2013 09:38, schrieb Kevin Wolf:
>> On Wed, Feb 20, 2013 at 06:26:55PM +0100, Andreas Färber wrote:
>>> Am 20.02.2013 18:05, schrieb Anthony Liguori:
>>>> Andreas Färber <afaerber@suse.de> writes:
>>>>
>>>>> Am 20.02.2013 14:43, schrieb Anthony Liguori:
>>>>>> This includes a de_DE translation from Kevin Wolf and an it translation from
>>>>>> Paolo Bonzini.
>>>>>>
>>>>>> Cc: Paolo Bonzini <pbonzini@redhat.com>
>>>>>> Cc: Kevin Wolf <kwolf@redhat.com>
>>>>>> Cc: Stefan Hajnoczi <stefanha@redhat.com>
>>>>>> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
>>>>>> ---
>>>>>> v1 -> v4
>>>>>>  - Don't use '|| exit 1' with sub-invocation of make
>>>>>>  - Actually include Kevin's translation
>>>>>> v4 -> v5
>>>>>>  - Update translations (Kevin and Paolo)
>>>>>>  - Fix 'make update' for it.po
>>>>>> ---
>>>>>>  Makefile       |  3 +++
>>>>>>  configure      |  4 +++-
>>>>>>  po/Makefile    | 46 ++++++++++++++++++++++++++++++++++++++++++++++
>>>>>>  po/de_DE.po    | 45 +++++++++++++++++++++++++++++++++++++++++++++
>>>>>>  po/it.po       | 45 +++++++++++++++++++++++++++++++++++++++++++++
>>>>>>  po/messages.po | 45 +++++++++++++++++++++++++++++++++++++++++++++
>>>>>>  ui/gtk.c       | 22 +++++++++++++++-------
>>>>>>  7 files changed, 202 insertions(+), 8 deletions(-)
>>>>>>  create mode 100644 po/Makefile
>>>>>>  create mode 100644 po/de_DE.po
>>>>>>  create mode 100644 po/it.po
>>>>>>  create mode 100644 po/messages.po
>>>>>
>>>>> IIUC this uses the English texts as key for lookup of translations.
>>>>> Experience shows that while that is most convenient for the English it
>>>>> leads to grammatical mistakes in other languages due to text reuse in
>>>>> wrong contexts. A prominent example is "Server" being translated as
>>>>> "Kellner" (which is waiter) in some early Windows NT version. :) More
>>>>> recent examples commonly found are ambiguities of, e.g., "Update" as
>>>>> noun vs. imperative - happens if the same wording is used in a menu and
>>>>> in some options dialog or status text. Similar for ing-forms translated
>>>>> as noun vs. infinitive vs. first-person present.
>>>>
>>>> Right or wrong, this is how GTK apps are written.  If you disagree with
>>>> it, take it up with the Gnome folks.  Consistency trumps "rightness"
>>>> here.
>>>
>>> You don't translate error_setg() et al., so translating a few UI items
>>> is in fact inconsistent here.
>> 
>> I think the plan with error messages was to have them translated
>> eventually, which is one of the reasons why clients may not parse them
>> (and strerror() results are already translated today).
>> 
>> But since we're using some standard GTK menu entries, not translating
>> would actually give you the much bigger inconsistency: In the same menu,
>> you would have both English and translated entries. This is what the
>> first version of this patch series had, and which I really hated.
>
> I agree that a mix of English and German is bad.
>
> Unfortunately that is exactly what I see on my German system now
> *despite* translation support (v5) being committed!

make install

Unfortunately, I have not found a way for it to pick up .mo files from
the build directory.

Regards,

Anthony Liguori

>
> Andreas
>
>> 
>> As long as there is a logical separation between translated and
>> untranslated strings (e.g. menus are translated, the monitor is English)
>> I don't see a problem with it.
>> 
>>> A more critical issue would be distro packaging though.
>>> An alternative idea would be to separate the _L() text from the English
>>> text if that is possible through some macro, cmp. reply to Daniel.
>> 
>> You want qemu to be usable with LANG=C, so using identifiers instead of
>> English texts doesn't really work. The gettext functions that allow
>> specifying a context look like a better solution to solve the problem
>> if it ever comes up.
>> 
>> Kevin
>> 
>
>
> -- 
> SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
> GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

Patch

diff --git a/Makefile b/Makefile
index 0d9099a..2262410 100644
--- a/Makefile
+++ b/Makefile
@@ -314,6 +314,9 @@  ifneq ($(BLOBS),)
 		$(INSTALL_DATA) $(SRC_PATH)/pc-bios/$$x "$(DESTDIR)$(qemu_datadir)"; \
 	done
 endif
+ifeq ($(CONFIG_GTK),y)
+	$(MAKE) -C po $@
+endif
 	$(INSTALL_DIR) "$(DESTDIR)$(qemu_datadir)/keymaps"
 	set -e; for x in $(KEYMAPS); do \
 		$(INSTALL_DATA) $(SRC_PATH)/pc-bios/keymaps/$$x "$(DESTDIR)$(qemu_datadir)/keymaps"; \
diff --git a/configure b/configure
index f33c10a..73576b8 100755
--- a/configure
+++ b/configure
@@ -3243,6 +3243,7 @@  fi
 
 qemu_confdir=$sysconfdir$confsuffix
 qemu_datadir=$datadir$confsuffix
+qemu_localedir="$datadir/locale"
 
 tools=""
 if test "$want_tools" = "yes" ; then
@@ -3416,6 +3417,7 @@  echo "qemu_localstatedir=$local_statedir" >> $config_host_mak
 echo "qemu_helperdir=$libexecdir" >> $config_host_mak
 echo "extra_cflags=$EXTRA_CFLAGS" >> $config_host_mak
 echo "extra_ldflags=$EXTRA_LDFLAGS" >> $config_host_mak
+echo "qemu_localedir=$qemu_localedir" >> $config_host_mak
 
 echo "ARCH=$ARCH" >> $config_host_mak
 if test "$debug_tcg" = "yes" ; then
@@ -4336,7 +4338,7 @@  DIRS="$DIRS roms/seabios roms/vgabios"
 DIRS="$DIRS qapi-generated"
 FILES="Makefile tests/tcg/Makefile qdict-test-data.txt"
 FILES="$FILES tests/tcg/cris/Makefile tests/tcg/cris/.gdbinit"
-FILES="$FILES tests/tcg/lm32/Makefile"
+FILES="$FILES tests/tcg/lm32/Makefile po/Makefile"
 FILES="$FILES pc-bios/optionrom/Makefile pc-bios/keymaps"
 FILES="$FILES pc-bios/spapr-rtas/Makefile"
 FILES="$FILES roms/seabios/Makefile roms/vgabios/Makefile"
diff --git a/po/Makefile b/po/Makefile
new file mode 100644
index 0000000..2b4420f
--- /dev/null
+++ b/po/Makefile
@@ -0,0 +1,46 @@ 
+# This makefile is very special as it's meant to build as part of the build
+# process and also within the source tree to update the translation files.
+
+VERSION=$(shell cat ../VERSION)
+TRANSLATIONS=de_DE it
+SRCS=$(addsuffix .po, $(TRANSLATIONS))
+OBJS=$(addsuffix .mo, $(TRANSLATIONS))
+
+SRC_PATH=..
+
+-include ../config-host.mak
+
+vpath %.po $(SRC_PATH)/po
+
+all:
+	@echo Use 'make update' to update translation files
+	@echo or us 'make build' or 'make install' to build and install
+	@echo the translation files
+
+update: $(SRCS)
+
+build: $(OBJS)
+
+clean:
+	$(RM) $(OBJS)
+
+install: $(OBJS)
+	for obj in $(OBJS); do \
+	    base=`basename $$obj .mo`; \
+	    $(INSTALL) -d $(DESTDIR)$(prefix)/share/locale/$$base/LC_MESSAGES; \
+	    $(INSTALL) -m644 $$obj $(DESTDIR)$(prefix)/share/locale/$$base/LC_MESSAGES/qemu.mo; \
+	done
+
+%.mo:
+	@msgfmt -o $@ $(SRC_PATH)/po/`basename $@ .mo`.po
+
+messages.po: $(SRC_PATH)/ui/gtk.c
+	@xgettext -o $@ --foreign-user --package-name=QEMU --package-version=1.0.50 --msgid-bugs-address=qemu-devel@nongnu.org -k_ -C $<
+
+de_DE.po: messages.po $(SRC_PATH)/ui/gtk.c
+	@msgmerge $@ $< > $@.bak && mv $@.bak $@
+
+it.po: messages.po $(SRC_PATH)/ui/gtk.c
+	@msgmerge $@ $< > $@.bak && mv $@.bak $@
+
+.PHONY: $(SRCS) clean all
diff --git a/po/de_DE.po b/po/de_DE.po
new file mode 100644
index 0000000..cb74d7c
--- /dev/null
+++ b/po/de_DE.po
@@ -0,0 +1,45 @@ 
+# German translation for QEMU.
+# This file is put in the public domain.
+# Kevin Wolf <kwolf@redhat.com>, 2012.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: QEMU 1.4.50\n"
+"Report-Msgid-Bugs-To: qemu-devel@nongnu.org\n"
+"POT-Creation-Date: 2013-02-08 09:21-0600\n"
+"PO-Revision-Date: 2012-02-28 16:00+0100\n"
+"Last-Translator: Kevin Wolf <kwolf@redhat.com>\n"
+"Language-Team: Deutsch <de@li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
+
+#: ../ui/gtk.c:990
+msgid "_File"
+msgstr "_Datei"
+
+#: ../ui/gtk.c:1000
+msgid "_View"
+msgstr "_Ansicht"
+
+#: ../ui/gtk.c:1002
+msgid "_Full Screen"
+msgstr "Voll_bild"
+
+#: ../ui/gtk.c:1029
+msgid "Zoom To _Fit"
+msgstr "Auf _Fenstergröße skalieren"
+
+#: ../ui/gtk.c:1035
+msgid "Grab On _Hover"
+msgstr "Tastatur _automatisch einfangen"
+
+#: ../ui/gtk.c:1038
+msgid "_Grab Input"
+msgstr "_Eingabegeräte einfangen"
+
+#: ../ui/gtk.c:1064
+msgid "Show _Tabs"
+msgstr "_Tableiste anzeigen"
diff --git a/po/it.po b/po/it.po
new file mode 100644
index 0000000..2b23491
--- /dev/null
+++ b/po/it.po
@@ -0,0 +1,45 @@ 
+# Italian translation for QEMU.
+# This file is put in the public domain.
+# Paolo Bonzini <pbonzini@redhat.com>, 2012.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: QEMU 1.4.50\n"
+"Report-Msgid-Bugs-To: qemu-devel@nongnu.org\n"
+"POT-Creation-Date: 2013-02-08 09:21-0600\n"
+"PO-Revision-Date: 2012-02-27 08:23+0100\n"
+"Last-Translator: Paolo Bonzini <pbonzini@redhat.com>\n"
+"Language-Team: Italian <it@li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+
+#: ../ui/gtk.c:990
+msgid "_File"
+msgstr "_File"
+
+#: ../ui/gtk.c:1000
+msgid "_View"
+msgstr "_Visualizza"
+
+#: ../ui/gtk.c:1002
+msgid "_Full Screen"
+msgstr "_Schermo intero"
+
+#: ../ui/gtk.c:1029
+msgid "Zoom To _Fit"
+msgstr "Adatta alla _finestra"
+
+#: ../ui/gtk.c:1035
+msgid "Grab On _Hover"
+msgstr "Cattura _automatica input"
+
+#: ../ui/gtk.c:1038
+msgid "_Grab Input"
+msgstr "_Cattura input"
+
+#: ../ui/gtk.c:1064
+msgid "Show _Tabs"
+msgstr "Mostra _tab"
diff --git a/po/messages.po b/po/messages.po
new file mode 100644
index 0000000..a90cd6f
--- /dev/null
+++ b/po/messages.po
@@ -0,0 +1,45 @@ 
+# SOME DESCRIPTIVE TITLE.
+# This file is put in the public domain.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: QEMU 1.4.50\n"
+"Report-Msgid-Bugs-To: qemu-devel@nongnu.org\n"
+"POT-Creation-Date: 2013-02-08 09:21-0600\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: ../ui/gtk.c:990
+msgid "_File"
+msgstr ""
+
+#: ../ui/gtk.c:1000
+msgid "_View"
+msgstr ""
+
+#: ../ui/gtk.c:1002
+msgid "_Full Screen"
+msgstr ""
+
+#: ../ui/gtk.c:1029
+msgid "Zoom To _Fit"
+msgstr ""
+
+#: ../ui/gtk.c:1035
+msgid "Grab On _Hover"
+msgstr ""
+
+#: ../ui/gtk.c:1038
+msgid "_Grab Input"
+msgstr ""
+
+#: ../ui/gtk.c:1064
+msgid "Show _Tabs"
+msgstr ""
diff --git a/ui/gtk.c b/ui/gtk.c
index 01a1777..ffa9baa 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -31,8 +31,12 @@ 
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
  */
 
+#define GETTEXT_PACKAGE "qemu"
+#define LOCALEDIR "po"
+
 #include <gtk/gtk.h>
 #include <gdk/gdkkeysyms.h>
+#include <glib/gi18n.h>
 #include <vte/vte.h>
 #include <sys/types.h>
 #include <sys/socket.h>
@@ -950,7 +954,7 @@  static void gd_create_menus(GtkDisplayState *s)
     accel_group = gtk_accel_group_new();
     s->file_menu = gtk_menu_new();
     gtk_menu_set_accel_group(GTK_MENU(s->file_menu), accel_group);
-    s->file_menu_item = gtk_menu_item_new_with_mnemonic("_File");
+    s->file_menu_item = gtk_menu_item_new_with_mnemonic(_("_File"));
 
     s->quit_item = gtk_image_menu_item_new_from_stock(GTK_STOCK_QUIT, NULL);
     gtk_stock_lookup(GTK_STOCK_QUIT, &item);
@@ -960,9 +964,9 @@  static void gd_create_menus(GtkDisplayState *s)
 
     s->view_menu = gtk_menu_new();
     gtk_menu_set_accel_group(GTK_MENU(s->view_menu), accel_group);
-    s->view_menu_item = gtk_menu_item_new_with_mnemonic("_View");
+    s->view_menu_item = gtk_menu_item_new_with_mnemonic(_("_View"));
 
-    s->full_screen_item = gtk_check_menu_item_new_with_mnemonic("_Full Screen");
+    s->full_screen_item = gtk_check_menu_item_new_with_mnemonic(_("_Full Screen"));
     gtk_menu_item_set_accel_path(GTK_MENU_ITEM(s->full_screen_item),
                                  "<QEMU>/View/Full Screen");
     gtk_accel_map_add_entry("<QEMU>/View/Full Screen", GDK_KEY_f, GDK_CONTROL_MASK | GDK_MOD1_MASK);
@@ -989,16 +993,16 @@  static void gd_create_menus(GtkDisplayState *s)
     gtk_accel_map_add_entry("<QEMU>/View/Zoom Fixed", GDK_KEY_0, GDK_CONTROL_MASK | GDK_MOD1_MASK);
     gtk_menu_append(GTK_MENU(s->view_menu), s->zoom_fixed_item);
 
-    s->zoom_fit_item = gtk_check_menu_item_new_with_mnemonic("Zoom To _Fit");
+    s->zoom_fit_item = gtk_check_menu_item_new_with_mnemonic(_("Zoom To _Fit"));
     gtk_menu_append(GTK_MENU(s->view_menu), s->zoom_fit_item);
 
     separator = gtk_separator_menu_item_new();
     gtk_menu_append(GTK_MENU(s->view_menu), separator);
 
-    s->grab_on_hover_item = gtk_check_menu_item_new_with_mnemonic("Grab On _Hover");
+    s->grab_on_hover_item = gtk_check_menu_item_new_with_mnemonic(_("Grab On _Hover"));
     gtk_menu_append(GTK_MENU(s->view_menu), s->grab_on_hover_item);
 
-    s->grab_item = gtk_check_menu_item_new_with_mnemonic("_Grab Input");
+    s->grab_item = gtk_check_menu_item_new_with_mnemonic(_("_Grab Input"));
     gtk_menu_item_set_accel_path(GTK_MENU_ITEM(s->grab_item),
                                  "<QEMU>/View/Grab Input");
     gtk_accel_map_add_entry("<QEMU>/View/Grab Input", GDK_KEY_g, GDK_CONTROL_MASK | GDK_MOD1_MASK);
@@ -1024,7 +1028,7 @@  static void gd_create_menus(GtkDisplayState *s)
     separator = gtk_separator_menu_item_new();
     gtk_menu_append(GTK_MENU(s->view_menu), separator);
 
-    s->show_tabs_item = gtk_check_menu_item_new_with_mnemonic("Show _Tabs");
+    s->show_tabs_item = gtk_check_menu_item_new_with_mnemonic(_("Show _Tabs"));
     gtk_menu_append(GTK_MENU(s->view_menu), s->show_tabs_item);
 
     g_object_set_data(G_OBJECT(s->window), "accel_group", accel_group);
@@ -1060,6 +1064,10 @@  void gtk_display_init(DisplayState *ds)
     s->scale_y = 1.0;
     s->free_scale = FALSE;
 
+    setlocale(LC_ALL, "");
+    bindtextdomain("qemu", CONFIG_QEMU_LOCALEDIR);
+    textdomain("qemu");
+
     s->null_cursor = gdk_cursor_new(GDK_BLANK_CURSOR);
 
     s->mouse_mode_notifier.notify = gd_mouse_mode_change;