Quirky text formatting when calling toUpperCase on translated string

I’m translating my English app to Spanish. If I call:

TRANS("some string who's resulting translation includes accents or tildes").toUpperCase();

the accented/tilded letters stay in lower case. Here’s an example with a tilded “n”:

24%20PM

My current workaround is to just manually type the Spanish string in as uppercase in the translation file. But sometimes I use a string in more than one place in the app, one in lowercase, the other in uppercase, so that workaround isn’t always feasible.

Is there a way around this?

For now I’ve added some manual replacements to the end of toUpperCase():

String String::toUpperCase() const
{
    StringCreationHelper builder (text);

    for (;;)
    {
        auto c = builder.source.toUpperCase();
        builder.write (c);

        if (c == 0)
            break;

        ++(builder.source);
    }
    
    String str = static_cast<String&&> (builder.result);
    
    str = str.replace("ñ", "Ñ");
    str = str.replace("á", "Á");
    str = str.replace("é", "É");
    str = str.replace("í", "Í");
    str = str.replace("ó", "Ó");
    str = str.replace("ú", "Ú");
    
    return str;
}

if there isn’t a very good reason to dynamically change the case for purposes of translation it is beneficial to use upper case string literals where ever upper case text should appear. a lot of languages have edge cases. frequently quoted ones are e.g. in german the letter ß would be SS in upper case or the letter i in turkish becomes İ.

Fair enough

FWIW we just call the std library’s upper/lower case conversion, so not really much we can do about that if it’s not performing as expected.

Which means, that the C-locale is used:
http://en.cppreference.com/w/cpp/string/byte/toupper

Would it be possible to add a String function to select an appropriate locale?

Why would we need to add anything to String for that? Could be done just by calling the appropriate std functions in your own code, I think?

True indeed, there is a workaround. My thinking was more so you don’t have to mix juce::String and std::String back and forth. But one can live without juce::String, if that’s the way to go :wink: