Possible buglet in International number handling


#1

hi Jules,

I’ve been messing with C++'s locale recently (trying to ensure apps work wherever they’re used in the World)… and I think I found something.

Setting the locale to Italian (which is one of those languages where a comma represents a decimal value (e.g. 0,5 is a half), and dot is the 1000’s delimiter e.g. EURO 1.234,12 )

double Slider::getValueFromText (const String& text) - has a hard-coded value which prevent the user using C++'s built-in ability to cope with numbers in locale format.

I think it should read:

return t.initialSectionContainingOnly (T("0123456789.,-")) .getDoubleValue();
just in case.

I haven’t found anywhere else where this happens - but I only had a quick check. (I dunno if this is a very elegant solution)

Also, I noticed that the value repopulated into a slider’s text label doesn’t match the locale rules (i.e. still uses a decimal-point) - I haven’t been able to find out why, yet. (This might be desirable in some countries, I guess)

Perhaps in: juce_string.cpp

might include
void String::doubleToStringWithDecPlaces (double n, int numDecPlaces) throw()

and reference

localeconv())->decimal_point rather than T(".")?


#2

Yes, I looked at some european figures the other day and thoguht the same thing… Not sure what the ideal solution is, but I should probably go through and replace any hard-coded '.'s with a locale-specific symbol. But then you have to deal with things like saved settings files where it might have been created in a different locale. It’s all a bit fiddly…


#3

On the plus side, it isn’t done very often (I only found it in the slider code, I think) - all the other stuff relies on C-libraries, down in the noise, and those take care of everything.

…But I see what you mean - it does tend to make the code much less elegant… but then again internationalization rarely is tidy, so hiding the dirty/swappy bit down in a base class would seem like a neater (and more powerful) choice.

For the XML (de-)serialization and wringing .ini files, it’s easy to revert to one standard (“C”'s default’s probably) - and restore to the current one (recorded on entry) on exit, if you see what I mean?

That said, if I’m one of the first to have this problem (and we’ll all be talking Chinese in 15 years time) it might not be worth it. :wink:


#4

You could TRANS() it, so if the user provides a translation for the “decimal” separator, use it, else use default.

By the way, it’s only for presentation that 3455.5 is written “3 455,5” in French or “3.455,5” in Italian…

So you only need to change code that is used to present /parse the number to / from the user. The storage code should still keep it in 3455.5 format.


#5

I’m not sure what you mean. Just translate “.” into “,” and vice-verse, just for the slider tell-back? I don’t think there’s any need - as JUCE uses C++'s standard routines everywhere-else, and they cope with things properly themselves.
i.e. apart from the hard-coded parsing of “.” (which in my view, should be comparing against the locale’s values of “decimal_point” (NOTE: not locale’s “mon_decimal_point”), and possibly ignoring characters which match locale’s “thousands_sep” (again, not it’s “mon_thousands_sep”)), everything else seems OK.
Values typed by the user (i.e. with or without separators, and with or without a decimal point) and the values displayed by the slider will be displayed correctly by the C standard routines, wrt locale.

Yes, but just for monetary values (LC_MONETARY), and I’m unlikely to use a slider for these values.

Yes, I wasn’t being very clear, but that’s what I was trying to get at with the last statement (about reverting to “C”'s (standard locale) for things like serializing values to files. It’s a bit messy - as it leaves the responsibility to the developer to ensure that they do the necessary work to ensure that the current locale info is stored and recovered, and that C’s default locale is used during serialization. Perhaps a comment/hint could be added to JUCE’s serialization code to remind them?

{:oops:Sorry, I didn’t intend to go on so much about it. It’s always a horrible subject, with no-end of nigglies to iron out - and even then not everyone will be pleased. I guess that’s how it is when standards committees like ANSI try to cover hundreds of years of diverse cultures’ quirks one document}


#6

In fact, I was speaking to Jules.

TRANS() is a macro defined in Jules that let you select a text/char translation based on “runtime” defineable language. This means that you can select US format even on a Italian computer (unlike C library local handling), provided you give the translation method (please have a look to LocalisedString).

This also mean you can develop English application on a French computer for example, and not fearing you’ll get unpredictable result on an English computer because the locale will have changed.

What I was saying is, if you’re going to change it, then only change it where it is meant to be displayed, so the parsing code doesn’t have to take locale into consideration, and work whatever language the user is using.