Merge translation files (.ts) with existing .ts files using QT Utilities (lconvert) - qt

Here's my problem: We've got .ts files for nine different languages for our product. We've added about 100 new strings that need to be translated, but some are for our next release, and some are for the release after that. We've run into problems with translators missing strings or translating strings ahead of time. We want to be able to send them smaller .ts file containing only the strings we want translated now, and then merge that .ts file into the larger .ts file containing the rest of the translation.
Our translators are required to use QT Linguist (previously we let them edit the raw XML with less than stellar results).
One solution would be to use contexts, but our dev team is not very keen on that idea. Another would be to merge the .ts files by hand, but that seems like a recipe for cut & paste errors.
Is there a method with lupdate & the project file to add or merge secondary .ts files? I've read through the forums in QT-land w/o finding the answer, but the switches in lupdate allude to being able to point to other translation files. Specifically the -pro switch which says:
-pro <filename>
Name of a .pro file. Useful for files with .pro file syntax but
different file suffix. Projects are recursed into and merged.
Example1: we have a German .ts file, we want to add 20 strings from a separate German translation file such that the primary translation file contains all the strings including the 20 new ones.
Example2: we have a German .ts file, we want to add 20 strings from a separate German translation file such that the secondary translation file will be merged with the primary during lupdate so that the resultant .qm file contains all the strings including the 20 new ones.
Has anyone done either of these (and either would work) and can you give me some insight?

The answer doesn't use lupdate, it lies in another utility called lconvert. It's quite easy to create a secondary file that only contains the strings you're interested in (and delete those same strings from the primary file), then run:
lconvert -i primary.ts secondary.ts -o complete.ts
This will take all the strings from the two input files and put them together into the output file. Using this method I was able to create a zero difference file (other than time stamp) of the original file that I'd split the two primary & secondary files from.
This question didn't get a lot of attention, but maybe someone will have this same problem and this will help.

thanks for this tip. It seems to work properly for my case :
I tried to extract updated and new strings from my project, which is currently under translation in an older version/release that I do not already have translated strings.
The problem was to send the new/updated strings only to translators.
I passed older strings in status resolved, adding new string using Lupdate, make a research using OxygenXML Editor with an XPath "/TS/context/message[not(translation/#type)]" to delete older strings, and clean it from useless blanks and carriage returns.
I tried a merge using lconvert with your solution, in order to merge translated strings : older and newer. It pass correctly lrelease and are displayed properly.

Related

How to extract infos in a .db file to create .csv or any viable "bookmark" file?

I am using a quite unknown bookmark manager on Android. I picked this one after trying others because it was possible to import, export, classify by folders, the design was good and it was easy to search in my bookmarks.
After importing all my bookmarks from other browsers and also from files, I started classifying all of them into folders, subfolders, etc..
I spent many days to classify them all as I wanted.
After classifying them, I tried to export them.
The problem is that the only option offered is to export them in a .html file, containing all the bookmarks but without any folder.
The .html file contains all my bookmarks but in complete desorder, and doesnt mention the folders.
In the app there was also a "backup" function, so I tried and it creates a .db file.
I opened this .db file with some SQLiteViewer app and I found written inside, among other things I dont understand, a list of all my bookmarks with a number next to each one of them, and also a list of my folders with next to them the corresponding number.
When I open the .db file, I have a choice between
-SQlite master
-android metadata
-bookmarks
-folders
-sqlite sequence
If I click on "Bookmarks", all my bookmarks are in a kind of spreadsheet with lines and columns. Next to them in another columns, for example for each bookmark related with "Kitchen recipes" it's written the number 1.
And in the "Folders" folder, next to the folder called "Recipes" its also written 1.
So I'm happy because it seems that my classification is stored in this file.
But the fact is I dont know how to extract easily all that data, and create with it a "bookmark" file importable in other bookmark app or browser ( for example .csv or .xbel or .html but with folders)
I guess I need some "script" working like this:
if the first raw in "Folders" got the number 8 next to it
Then take all the bookmarks in the "bookmarks" folder that also got an 8 written next to it, and put it inside this folder.
I'm a complete noob in coding, I dont know what is SQlite, nor anything.
So i know that maybe I am asking for too much informations at the same time.
But if some kind person could put me in the way, by explaining me if
thats possible
what would be the easiest way
if some solution already exist
if someone like me can do it and what do I have to learn if I want some day to be able to do it
Thanks
Here's pictures so you understand easier:
Sqlite
Folders
Bookmarks

Open a XML file not knowing the complete name and parse xml

I am using robot framework with RIDE, and for a test I need to find a XML file on my computer and open it to parse the xml and be able to use the datas.
The thing is that I don't know the exact name of the file; the format is numberNameOfTheFile, so it could be 1NameOfTheFile or 25NameOfTheFile.
How can I use regexp in my keyword? Or any other way to achieve this?
Thank you
How would you do it manually - how would you pick the file to use for the verification?
I presume, you are going to look at all the files that are matching a specific name pattern; in Robot Framework you can do that with OperatingSystem's List Files In Directory keyword, which supports passing a name pattern:
${the files}= List Files In Directory /the/path/to/the/dir *NameOfTheFile.xml
Now you have a list object with the filenames that match; if it's empty - there's no such file, which may be a problem (depends on your test/reqs, I don't know). If it has a single member - great, that's your file.
And if there are multiple files - that's another "problem". How would you pick the right file manually? It could be that the newest file is the target one - for that you would go over all of them and find the one through OperatingSystem's Get Modified Tume; or it can be the largest; or the number in its suffix would be the biggest. This really depends on your requirements, and what you are trying to achieve.
"How would you do it manually" is probably the most important question to ask. Think and break down to steps the individual tasks you would do, and now you have the algorithm; see how to put that in code - and presto, the implementation. This applies to scripts, test cases, and business process automation (e.g. software).
I was tempted to mark the question for closing, because precisely this - the algorithm - was missing, only the end goal is stated - while SO is for helping in the implementation part. But, here we are :)

Comment in aspell .dic files?

They look like this:
abaft
abbreviation/M
abdicate/DNGSn
Abelard/M
abider/M
Abidjan
ablaze
abloom
I am using this kind of dictionary with Node.js application, but I will need it to be smarter. Specifically, I want to remember occurrence probability of every word based on already processed text. I'd like to save this information in existing .dic file - but how to do that without making it invalid?
Is there any comment syntax that would allow me to store additional data next to the words in file? Such that normal dictionary parser will ignore it?

Add entries to Info.plist in Qt

In Qt, it is possible to specify an Info.plist file to use when building on Mac, as follows:
QMAKE_INFO_PLIST = MyInfo.plist
This replaces the Qt auto-generated Info.plist file with another one.
Rather than replace Qt's auto generated one entirely, is it possible to add individual entries?
I don't think it will make little practical difference but I'd like to be able to do it because I feel it would be "tidier" to just add the additional items I want rather than brutally replace the whole file.
Unfortunately this is impossible. But Qt makes your life easier with some variables that you can use in plist file. From Qt documentation:
In the .plist file, you can define some variables, e.g., #EXECUTABLE#,
which qmake will replace with the actual executable name. Other
variables include #ICON#, #TYPEINFO#, #LIBRARY#, and #SHORT_VERSION#.
Find a file named 'Info.list.app'. This is the template of Info.list. You can use it as a start point and append you own entries. It is typically location like Qt5.7.0/Src/qtbase/mkspecs/macx-ios-clang/Info.plist.app in your QT root dir.
See Qt documentation for more detail.

Translate QT application without text in code

Is there a way to translate a QT app into different languages without defining the texts directly in the source? I want to separate the text from source. This would result in some kind of resource files for ALL languages, including the default language (e.g. English).
You won't be able to leave the English (or your source language, not necessarily English) source out of the XML (.ts) files as lupdate will put it there each time you run it. However as long as a translation exists for the chosen language, the source text will be ignored. If there is no translation text, it will default to the source text. This is useful since you'll be guaranteed to get some sort of text in your translation, but it'll be up to your test team to insure that the translations exist. I wrote a python script to automate the checking of the translation files since we have 9 languages and nearly 1k strings per translation. To test for this, we used a very simple sed script to create pseudo-loc source strings so if there were translations missing, the pseudo-loc text would be very evident.
Regarding the process for editing the .ts files, we farmed out the translations to individual translators, providing them with the .ts file for their language, and usually about an hour's worth of hand's on instruction in using QT Linguist. If the translator was onsite and wanted to see their translations on our device immediately, I wrote an autorun script that would place the resultant .qm file in the right place in our embedded file system and restart the application to display the new translations. If they weren't onsite, we'd run them through the python script mentioned above to check for a number of different problems, then simply check in the .ts file so it'd get built the next time around.
HTH
You might be able to use the QT_TRANSLATE_NOOP family of macros to do what you want. Those simply mark some text as "need to be translated" so that lupdate picks it up, but you can refer to those translated values by variable constants in your code. So ...
const char *kHelloWorld = QT_TRANSLATE_NOOP("SomeScope", "Hello world");
Later...
return qApp->translate("SomeScope", kHelloWorld);
This is still in your source code somewhere, but it is at least one step removed. You could theoretically have the QT_TRANSLATE_NOOP stuff in an entirely different Qt project, but then you'd need some way in your real project to know what you are supposed to translate. (You still need the char* constants somewhere.)
What are you trying to accomplish exactly by not having the English text in the source? That might help people provide more appropriate answers.
EDIT
Based on your comment below about intended usage
OK, then this is precisely what the normal Qt translation process does. Running lupdate creates those XML files (they have a .ts extension). They can be opened by translators in the very-easy-to-use Qt Linguist. They are translated, then sent back to you (the programmer), where you run lrelease on them to create the binary translation files you will ship with the app. The translations are resolved at runtime, so there is no need to recompile.
If you wanted to enable a user to do this, you would:
Ship your application with an empty (untranslated) .ts file and the lrelease program.
Provide instructions on how to use Qt Linguist to translate. (They could use a text editor and modify the Xml directly, but it's a lot easier with Linguist.)
Explain how to run lrelease and where to drop the binary translation files so that your application pulls them in.
On this last step, you could theoretically provide a nice wizard-like app that hides the implementation details.
What we will do is:
* Include a translation for the former default language. Using this *.ts file to auto-generate the other *.ts files. This is required as we keep the translations outside the QT environment as they match with other projects not related to QT.
Then have only have to make sure this translation contains the correct value.
In the future we can define IDs in the code witch represent Text in the default translation. Like translating TXT_ID_ABOUT to "About".

Resources