New i18n interface for KDE 4, second try

Nicolas Goutte nicolasg at
Fri Oct 28 14:48:40 BST 2005

On Friday 28 October 2005 15:19, Chusslove Illich wrote:
> > [: Nicolas Goutte :]
> > As nobody has commented yet, I think that it is my turn. :-)
> No need to wait ;)

Well, I would have liked input from other people too.

(I suppose that we start to know each others' position about the subject.)

> >> [: Chusslove Illich :]
> >> [...] there can also exist a set of simple templates which mimick
> >> variable argument list, so that this can be used:
> >>
> >> i18n("Blah, blah: %1 %2", foo, bar); // ordinary
> >> i18nc("This is for...", "Blah, blah: %1 %2", foo, bar); // context
> >> i18np("One thingy with %1", "%n thingies with %1", n, whatnot); // plur
> >
> > [: Nicolas Goutte :]
> > I would be careful such a solution.
> >
> > First it is going back into printf and friends. Probably you will force
> > the parameters to be strings to avoid printf-like problems but then it
> > makes the solution less flexible [...]
> Say, when compiler encounters:
> i18n("Blah, blah: %1 %2", foo, bar);
> it will match the call to this particular template:
> class KTrString {
>   ...
>   template <typename A1, typename A2>
>   friend i18n (const char *text, const A1 &a1, const A2 &a2) {
>     KTrString(text).arg(a1).arg(a2).toString();
>   }
>   ...
> }
> Since this template is defined inline, and is simple enough, compiler will
> inline it, so the original call will be compiled as:
> KTrString("Blah, blah: %1 %2").arg(foo).arg(bar).toString();
> Thus, no loss of flexibility. Minus .toString() finalization, this would be
> same as what QString's arg() methods do (KTrString's ones just record the
> parameters additionally).

Ah, good, I see. Sorry, I have missed that entirely.

Remains one case: what if the parameter is too of kind KTrString?

> >> [: Chusslove Illich :]
> >> Templates would be declared up to some limited number of arguments
> >> [...] I found seven messages with more than %8, two with more than %10.
> >
> > [: Nicolas Goutte :]
> > But what is the drawback (code length, time) to always handle 10 QString
> > objects?
> The previous apply, there is no extra here, as calls are inlined.
> > (Qt has defined at QString::arg for at most 4 QStrings, so probably
> > there is a reason.)
> This is only for an odd situation where an argument itself contains a
> placeholder. Eg.:
> QString foo = "Hey, %1!";
> QString bar = "what";
> QString msg = QString("%1 and %2?").arg(foo).arg(bar);
> Then msg would become "Hey, what! and %2?", because bar would replace the
> placeholder from foo. Instead, if the call is:
> QString msg = QString("%1 and %2").arg(foo, bar);
> The result would be "Hey, %1! and what?".
> Depends what one wants...

"That is not a bug but a feature." :-)

No, seriously, sometimes the string has % in it and it should not be replaced. 
(That is why there are the QString::arg with multiple QString to avoid that a 
%2 in the first argument is replaced by the second argument.)

> > The similarity between these 3 functions' names [i18n, i18nc, i18np]
> > makes that a missed letter or a typo, makes the result in the PO(T)
> > file quite different. That could lead to a nightmare for translators
> > if there are many of such entries to be corrected (even more if it is
> > at message-freeze time).
> Before translators, it is actually a problem for programmers themselves.

Yes and no. I prefer to allow the computer to tell that something is wrong 
than to have to look at Scripty's log to find that there is a problem.

The compiler output is read by the corresponding developer, Scripty's output 
is not. (Not sure if Scripty's log is read by more than 2 people anyway...)

> For example, when giving context, if they forget to specify correct call
> name:
> i18n("This is entry in menu Session", "New");
> the result would be that in runtime it shows "This is entry in menu
> Session" instead of "New" :) And a warning message about too many
> parameters would appear in the shell output.

Yes, but it is not as good...

> So, I thought this is not a problem because programmers themselves would
> see the error when they run the program. But now another scenario occured
> to me: what if someone just adds a comment at a later point? Hey, just a
> comment, no biggy, why check that part of GUI again? *But*, if again the
> change in call name is forgotten... How big a problem this really is, any
> way to automatically avoid it?

...especially for plural form, as the singular is a valid value.

> > Note if it is QString::arg which makes problems, so that you do not want
> > a KI18N::arg, then perhaps give it another name like KI18n::param:
> >
> > i18n("Foo %1").param("Bar");
> > i18n_plural("A Foo %1", "%n Foos %1", count).param("Bar");
> > i18n_context("FooContext", "Foo %1").param("Bar");
> >
> > [...] it [also] allows to keep the i18n() for all three names.
> It is not a problem with the name of argument addition method, but what
> would convert the KTrString into a QString then? In non-inherited case,
> like here, one needs an extra method for that (toString); in inherited
> case, it happens automatically by upcasting, but the possibility to check
> if enough arguments have been supplied is lost, and there are those hacks
> needed...

> > Note: I would avoid Tr in the name, as we are using Gettext and not
> > Qt's translation system.
> This naming thing is getting ridiculous, why not just call it

Well, people makes associations. If they see tr in Qt and Tr in such a class, 
the y wil think: "Hey! KDE can use Qt's!" but that will be wrong.

> KRainDeerString or something (*zhwanggg*) Ok, how about KLocaleString?

KLocalizedString ?

Have a nice day!

More information about the kde-core-devel mailing list