QT How to find untranslated strings - c++

I am testing a QT application I am internationalizing. I think I have found all the strings that need processing through tr() or ::Translate(). I think I have handled all occurrences.
I have gotten back the first rounds of translations (done through Qt linguist tool).
Through QA testing I want to make sure all strings are translated and if possible I would like to easily identify any that are not translated and why.
What tools or methods are available for this?

I have discovered
lrelease -markuntranslated <prefix>
This takes any strings in the .ts file that are untranslated and prepends prefix
If the label "do it now" is in the .ts file and it is not translated in Qt linguist, then if you run lrelease with
-markuntranslated NT-
then you will see the label presented when you run the application as 'NT-do it now'.
This makes it obvious for whomever is testing that the problem is a string that has been processed via ::Translate() or tr(), but which has not been translated in QT linguist.
And any wholly original strings in the UI of the running application must thus be fully untouched by any of the QT translation machinery.
see lrelease -help for more info.

Related

How to properly embed Qt 5.15 localizations in an iOS application

Qt 5.15 introduces (at least I believe it is new to 5.15) .ts files, to allow for properly handling multi-locale text in an application. I'm updating an iOS Qt app from 5.X, where X knows nothing about .ts files. On startup, I'm getting a warning that indicates that there is an app-specific translation set (which is true), but that there is no translation for Qt's own text (things like warning text and dialog prompts). The documentation says, that these translations are in the Qt5 source directory (currently usually /tqtc-qt5) in the qtttranslations folder. Thus sayeth this doc https://doc.qt.io/qt-5/ios-platform-notes.html#application-assets. Examples show only app-unique text translations, not Qt's "built-in" text. So real quick, I'm going list my assumptions, so that they can be corrected or confirmed.
Qt has always had embedded text of its own, but 5.15 introduces a way to ensure that your multi-locale ready app has all the correctly translated "built-in" text available.
Only the app-writer knows what modules they are using, so it is the app-writer's responsibility to specify which set of translations are added to the app's resources for handling different locales. (per this document - https://doc.qt.io/qt-5/qmake-variable-reference.html#translations)
According to the above two docs, for example, if I use basic Qt functionality and QML, AND I have a single app with tier-one language support for, say, English, German, and French, it appears that my app's .pro file should include something like
TRANSLATIONS += <path_to_qt5>/qttranslations/qtbase_en.ts
TRANSLATIONS += <path_to_qt5>/qttranslations/qtbase_de.ts
TRANSLATIONS += <path_to_qt5>/qttranslations/qtbase_fr.ts
TRANSLATIONS += <path_to_qt5>/qttranslations/qtdeclarative_en.ts
TRANSLATIONS += <path_to_qt5>/qttranslations/qtdeclarative_de.ts
TRANSLATIONS += <path_to_qt5>/qttranslations/qtdeclarative_fr.ts
CONFIG += lrelease embed_translations
I've traced though the Qt source in the debugger to the point where it is complaining about the missing translations. It is looking for qt*_*.qm, where the first wildcard is your module ("base", "declarative", etc) and the second is your two-letter language code. So, should I be explicitly adding .qm files as resources in my iOS bundle, or is TRANSLATIONS += foo_ln.ts implicitly doing this embedding in response to CONFIG += lrelease embed_translations. One things is certain: right now, my naive porting of an older .pro file does nothing with respect the TRANSLATIONS property AND Qt is cranky about the missing .qm files in my bundle. It's a warning, not a critical fail, so I assume in a pinch, it would put up US english text, which seems to be the baseline for translations and is embedded in the source (not the bundle) by default. Do my example additions to the .pro file in point 3 above seem sufficient, or is there more to do? Or is there less to do? Is there a .pro directive that I've missed in the docs that says "do the right thing with international translations of Qt-inherent strings"? There is in a addition to the listed .ts files a "qt_*.ts" file set. Is this just everything whether I need it or not, for lazy people who don't care about lugging around a few extra strings? Finally, there is also EXTRA_TRANSLATIONS which is like TRANSLATIONS, only it does not go through the lupdate during the build. Now I'm pretty unclear on the function of lupdate relative to lrelease, but is it the case that one is for "stock" Qt strings, and the other for App-specific translations (because they may be "updated" due to changes during development)? The semantics just don't make sense to me right now, nor do my responsibilities to handle these matters in the "right" way.
I'd like to answer my own question because it turns out many of the above assumptions were just wrong, and it took deeper dives into the source code and the debugger to get my head straight, but now I have Wisdom. The documents I was reading was about how to include raw translation files "(.ts files)" into an app being built with qmake. As is typical with Qt, building with qmake or Qt Creator solves most of your problems automatically, with your part being to provide only the small amount of specification needed to execute your app. The app I'm working on however is monstrously huge, old, and overly-complicated, so I spend a lot of time hunting down the most obscure Qt and CMake features to cobble this Frankenstein's monster of an app together. The problem I was trying to solve is simply providing to Qt its own text localization files for a multi-locale app. The app-specific ones were fine, but Qt was wagging its finger at me and complaining that it couldn't find its own. So the .ts files it turns out are not a thing for this kind of task - they are simply part of the pipeline of getting data from a translation house in a consumable form. During Qt's own configure and build (yes we build Qt from source), it handles the compiling of raw .ts files into .qm files, suitable for use by the framework's translator objects. Those are all just sitting in qtbase/translations ready to be integrated into the app installation. The problem was that we (the group who developed this app long ago and which I am now reviving) didn't handle the iOS case. This is a special case that requires some choices. You can put translation files in the app's bundle at a specific path, you can home-brew some exotic URL resolution whereby you feed the translator the contents of the .qm files on demand, or you can compile them all into a .qrc file and position them in your resource tree. That last is what we did with the app-specific translations, so I mimicked it for Qt's, filtering the total set of .qm files for the modules we use and for the locales in our tier-one localization target languages. This involved a complicated python script, and a few extra lines of Cmake, including one very elusive one (QINIT_RESOURCES) that gated everything until I realized it was needed for this platform. I'm only wrapping this up, so if anyone else is confused enough to find this question, that there are some general comments to set things straight.

How to translate certain string from lib?

django-registration is missing some translations for german.
See github Search for "". Translations are were but "broken".
I don't want to fork or change localization files localy.
Is it possible to provide translation for some strings in my app/project?
You just mention the 2 methods that are candidates for the translation of a string. If you do not want to fork the project nor change the localized files then I believe there is no other way of translating it.
Last resort method: Make an identical file of django-registration that includes the to-be-translated string and add translations there.
IMO the only way is to fork the project, run ./manage.py makemessages and voila! Translations are there. Another thing you can do is to try to contribute to this package by fork it first and then make a pull request! That's the beauty of open sourcing!

Good way to maintain Qt labels and text on UI

What is the best way/common practice for maintaining all string resources found on a UI in Qt, especially the textual input/text in combo boxes etc. (since these are the once that are frequently used in the code itself)?
I know that Android has this string resources thing such that resources only have to be modified at one position.
Does Qt have something like that too or do I have to initialize string resources in code instead of in the UI's XML itself...
AFAIK, there is no built-in mechanism for string resources in Qt. If you want to maintain strings at build time you can define them in one .h/.cpp file as global variables and reuse them in your code.
Otherwise you can use Qt's translator files (binary) and load them along with your application. If you need to change a string, you simply will need to edit the translation file (xml) and "recompile" it with lrelease utility without building the application again.
There is a mechanism to dynamically translate texts in application, but it works a bit different than Android string resources, but achieves the same goals.
Qt uses i18n system modelled after standard, well known unix gettext. It works in a very similar way to iOS NSLocalizedString, if that rings a bell.
http://doc.qt.io/qt-5/qobject.html#tr
This is worth reading too:
http://en.wikipedia.org/wiki/Gettext
http://doc.qt.io/qt-5/internationalization.html
Android approach is a bit unique and you should not expect it to be a "standard everywhere". It works, it's ok, but it's not a standard way of doing things on desktop.

Proofread strings with Qt Linguist

Our main language is English, so we use tr("Some english text") all over the source code.
We also plan to translate it to several different languages - no problem with that.
Our customer wants to get all phrases from the source code and proofread them.
Of course, we should put those phrases back after proofreading.
How can we accomplish that in a proper way? Maybe Qt Linguist allow to export/import embedded localizable texts?
I guess the customer can just translate English into English and then we can use that English translation, but it's weird.
I would go with Qt's lupdate utility (could be found in Qt's bin directory) that will extract all string literals from your sources into a xml (ts) file. The file can be opened with Linguist tool.
Note, that the utility considers only strings surrounded with tr() macro. Here is luptdate description:
lupdate is part of Qt's Linguist tool chain. It extracts translatable
messages from Qt UI files, C++, Java and JavaScript/QtScript source
code. Extracted messages are stored in textual translation source
files (typically Qt TS XML). New and modified messages can be merged
into existing TS files.
UPDATE:
Another alternative is keeping all string literals definitions in a separate source file and update it once customer has corrected all strings. I believe this happens not so frequently, or even only once, so it would not be worth of much effort with translations etc.
Finally, it looks like I will have to update phrases (embedded into source code) by hand. Actually, it shouldn't take too much time. If I have time to write a script on Python I will update this post.
UPDATE
So, I made everything "by hand" with a little help from Sublime Text 3.
Find all matches in repository folder using the following regular expression (.*)(tr\((\"(.+?)\")\))(.*)
Copy the search results into new document
Using the same regular expression do the search again and replace each match with \4 - this capture group represents text in tr("").
After receiving phrases from the customer after proofreading, it took 3-5 minutes to find differences with diff tool and update phrases in code.
Not a true-programmer way of resolving problems but worked for me and worked pretty fast!

Do you know of a good program for editing/translating resource (.rc) files?

I'm building a C++/MFC program in a multilingual environment. I have one main (national) language and three international languages. Every time I add a feature to the program I have to keep the international languages up-to-date with the national one. The resource editor in Visual Studio is not very helpful because I frequently end up leaving a string, dialog box, etc., untranslated.
I wonder if you guys know of a program that can edit resource (.rc) files and
Build a file that includes only the strings to be translated and their respective IDs and accepts the same (or similar) file in another language (this would be helpful since usually the translation is done by someone else), or
Handle the translations itself, allowing to view the same string in different languages at the same time.
In my experience, internationalization requires a little more than translating strings. Many strings when translated, require more space on a dialog. Because of this it's useful to be able to customize the dialogs for each language. Otherwise you have to create dialogs with extra space for the translated strings which then looks less than optimal when displayed in English.
Quite a while back I was using a translation tool for an MFC application but the company that produced the software stopped selling it. When I tried to find a reasonably priced replacement I did not find one.
Check out Lingobit Localizer. Expensive, but well worth it.
Here's a script I use to generate resource files for testing in different languages. It just parses a response from babelfish so clearly the translation will be about as high quality as that done by a drunken monkey, but it's useful for testing and such
for i in $trfile
do
key=`echo $i | sed 's/^\(.*\)=\(.*\)$/\1/g'`
value=`echo $i | sed 's/^\(.*\)=\(.*\)$/\2/g'`
url="http://babelfish.altavista.com/tr?doit=done&intl=1&tt=urltext&lp=$langs&btnTrTxt=Translate&trtext=$value"
wget -O foo.html -A "$agent" "$url" *&> /dev/null
tx=`grep "<td bgcolor=white class=s><div style=padding:10px;>" foo.html`
tx=`echo $tx | iconv -f latin1 -t utf-8 | sed 's/<td bgcolor=white class=s><div style=padding:10px;>\(.*\)<\/div><\/td>/\1/g'`
echo $key=$tx
done
rm foo.html
Check out appTranslator, its relatively cheap and works rather well. The guy developing it is really responsive to enhancement requests and bug report, so you get really good support.
You might take a look at Sisulizer http://www.sisulizer.com. Expensive though. We're evaluating it for use at my company to manage the headache of ongoing translation. I read on their About page that the company was founded by people who left Multilizer and other similar companies.
If there isn't one, it would be pretty easy to loop through all the strings in a resource a compare them to the international resources. You could probably do this with a simple grid.
In the end we have ended up building our own external tools to manage this. Our devs work in the english string table and every automated build sends our strings that have been added/changed and deleted to translation manager. He can also run a report at anytime from an old build to determine what is required for translation.
Check out RC-WinTrans. Its a commercial tool that my company uses. It basically imports our .RC files (or .resx files) into a database which we send to a different office for translation. The tool can then export a translated .RC file (or .resx file) for each language from the database. It even has a basic dialog box editor so the translator can adjust the size of various controls in the dialog box to be sure the translated text fits.
It also accepts a number of command line arguments and has a COM automation interface so you can integrate it into a build process more easily. It works quite well for us and we literally have thousands and thousands of strings and dialog boxes, etc.
(We currently have version 7 so what I've said might be a little bit different than their latest version 8.)
Also try AppTranslator: http://www.apptranslator.com/. It has a build-in resource editor so that translators can, for example, enlargen a text box when need bo. It has separate versions for developers and translators and much more.
We are using Multilizer (http://www.multilizer.com/) and although sometimes it's a bit tricky to use, at the end with a bit of patient it works pretty well.
We even have a translation web site where translators can download our projects and then upload the translations using Multilizer command-line features.
Managing localization and translations using .rc files and Visual Studio is not a good idea. It's much smarter (though counter-intuitive) to start localization through the exe. Read here why: http://www.apptranslator.com/misconceptions.html
I've written this recently, which integrates into VS:
https://github.com/ekkis/Powershell/blob/master/MT.ps1
largely because I was unsatisfied with the solutions out there. you'll need to get a client id from M$ (but they give you 2M words/month translation free - not bad)
ResxCrunch will be out soon, it will edit multiple resource files in multiple languages in one single table.