A nice picture of a cutie cat… although I’m really looking for a cutie linguist and didn’t think it would be appropriate to share my vision for that! More seriously the truth isn’t as risqué… I’m really after Qt Linguist. Now maybe you come across this more often than I do so the solutions for dealing with files from the Qt product, often shared as *.TS files, may simply role off your tongue. I think the first time I saw them I just looked at the format with a text editor, saw they looked pretty simple and created a custom filetype to deal with them in Studio 2009. Since that date I’ve only been asked a handful of times so I don’t think about this a lot… in fact the cutie cat would get more attention! But in the last few weeks I’ve been asked four times by different people and I’ve seen a question on proZ so I thought it may be worth looking a little deeper.
The format of the *.TS files are XML, or at least the ones I have seen so far are. In fact the format for the files I have seen so far seem very straightforward so I knocked one up with two strings like this:
All I had to do to handle this was create a couple of parser rules to extract the text from the target file when the type attribute in the translation element said “unfinished”, so like this:
I could even create a custom preview to show me all the other segments and comments if I needed to provide some context to the translator while they worked on the translatable text. So all good, and simple to achieve. But what if the file needed to be reviewed, so you need to see source and target for example? Here I’d have a problem because the custom XML filetype I created is monolongual. So to solve that one I’d need to transform the file to XLIFF or get a developer to create a custom filetype for *.TS files so it could be handled as a bilingual XML file. All possible! But then it was suggested by a few translators in the SDL Community that Qt Linguist was the way to go as this should support an export to XLIFF… only problem was it’s not that easy to get hold of. So let’s look at that problem!
QT Linguist
Evzen Polenka, in his inimitable style, advised that the main problem is to get hold of Qt Linguist because the Qt developers don’t provide separate Linguist builds. So you either have to download and install the complete Qt framework, or google quite hard for Linguist builds created by other people. (I left out all the colourful parts… google Qt Linguist in the SDL Community if you want to enjoy the whole conversation!)
So a bit of googling and I discovered that the application can be found in the Google Code Archive. but if you look there and navigate to the downloads you’ll see the latest version available is 4.6 and it’s dated Dec 4, 2009. Quite old and everyone thinks there’s a newer one:
So I emailed the people at Qt who first of all wanted to know my licence ID which I don’t have… guess they saw me as a commercial user. So after explaining what I needed, just to be able to help translators handle *.TS files in their preferred translation tool I received some useful hints:
Qt comes with a localization tool, Qt Linguist, which has the best support for translating Qt applications. The latest released Qt Linguist version can be downloaded and installed with Qt 5.8: https://www.qt.io/download/ The page has the following instructions that you might find useful: The "native" tool for translating TS files is Qt Linguist. It is pretty self-explanatory and comes with documentation. If you prefer to use another tool (most probably because of better support for translation memory), you might need to convert the TS files to and from some other format: $ lconvert .ts -o .po $ .po $ lconvert -locations relative .po -o .ts XLIFF might also work for your tool. Note: Always use the latest stable linguist tools available. Also, 3rd party tools like ts2po were known to cause trouble.
This seems to be quite helpful and makes me think there is a command line possibility for batch converting which is probably attractive for localization engineers, but also confirms the observations from Evzen that the only way to get the latest version of the tool is to take the entire package to get the latest Qt Linguist version. So I followed the link and navigated to and chose the online installer which was a 17Mb download, but this then runs through an installation process which takes up 20Gb of disk space based on me selecting the 5.8 version mentioned above. Once this was complete I could open and run Qt Creator. What I couldn’t do is easily see how to get at Qt Linguist so I looked up in the manual and found this:
Qt Linguist is a tool for adding translations to Qt applications. Once you have installed Qt, you can start Qt Linguist in the same way as any other application on the development host.
For someone not familiar with Qt this isn’t too helpful. So I searched for linguist.exe in windows which is the program in the Google Code Archive and found 5 instances of it in my new Qt folder, all of which started Qt Linguist version 5.8. So that worked, and now I can run the latest version, but I needed a pretty hefty download and install just to get it. But now I can open my source *.TS file in Qt Linguist and it looks like this:
I’m not sure there is a visible difference between the way in which I want to use this tool for conversion only in version 4.6 compared to version 5.8, but there may well be bug fixes and improvements in the latest build so if you handle these files a lot it makes sense to take the latest one. I just wish that Qt provided an installer for the Qt Linguist version as a standalone tool as available in the Google Code Archive because then it would be lot easier for translators who really don’t need, or want, the other tools.
***Update***
Also adding to this post that as mentioned in the comments below Evzen had found a bug report that I didn’t read in which there is a link to a separate github repository containing the installers for Qt Linguist itself. Clearly much easier than the convoluted process I just went through but still an unofficial solution. They do seem to have recognised the need to support translators with this build and the bug report is an enhancement request to provide the separate installers officially. But the rest of the article is hopefully still useful and it might be useful for the Qt guys to read this too in case anyone else asks them the same question I did, and in case they need more information to support the enhancement request.
***end***
Going back to the SDL Community I also read another good tip, this time from Christine Bruckner who advised that she converts the *.TS files to *.PO as opposed to *.XLF because this way she can use embedded content rules to handle embedded content. Qt Linguist is capable of doing both so you can decide for yourself. There are advantages and disadvantages of them all. Using my simple two string test file as an example I made a few simple observations below.
Exporting to XLF
The first thing is that the languages are recognised if you use *.XLF. They are not in *.PO or *.TS using a custom XML filetype:
The second thing I thought would be helpful is that the statuses of the segments can be mapped. Using the defaults I see this in Studio:
So using the defaults “Signed off” and “Draft” compares to “Accepted/Correct” and “Not accepted” in Qt Linguist:
I could change this and map something different but it works for me. However, one thing I did notice is that whilst Studio uses the XLIFF attribute to determine the status, Qt uses them in the export file but ignores them in the import file as it wants to see the optional “approved” attribute on the trans-unit. So it expects to see something like this:
Studio doesn’t use this optional attribute so the file will always come back into Qt Linguist with the “Not accepted” status and will have to be updated in there. If anyone found a workaround to this in Studio other than running a regex search/replace on the final XLIFF perhaps share it here.
The other useful feature is that the “translatorcomment” is also visible with the XLIFF filetype:
Exporting to PO
The obvious advantage here is the ability to handle embedded content. I think it’s pretty common in *.TS files to have placeholders throughout the strings and these can be handled quite easily in both the out of the box PO filetype in Studio and also the PO filetype on the SDL Appstore (created by SuperText). The Studio PO filetype will represent the strings as follows:
Interesting that they are given an AT status, although the segment translation status is the same as for XLIFF as well as the comment being shown in the comments view. The AppStore PO does not extract the comments so it’s worth noting this, although I imagine the SuperText guys could enhance it if they see the need, but it also uses the AT status. In truth this is probably a more accurate reflection of the translation origin seeing as it’s come from another tool with no match value provided.
The other difference is that the “approved” status used in Qt is supported much better through the use of the PO filetype as this returns the target file like this:
So for me, using *.PO is a better bilingual filetype to use when working with these Qt files because of the work that will be saved in not having to manually approve all the translations you are already happy with in Qt Linguist and also in being able to handle any embedded content.
Custom XML
I’m going to mention this one but in reality I think the best solution here is to ask a developer to create a bilingual filetype to support *.TS files. The format is very simple and it’s probably not a difficult thing to do. The benefit is that there would be no need to go through all this hassle of getting hold of Qt Linguist in the first place if you happen to be working for a client who doesn’t export the files for you as *.PO or *.XLF. I think a variant of the existing PO filetypes would probably be a very good starting point as you’d have the framework already in place.
But as a monolingual filetype, if you are fortunate to have a file that is prepared in a way to support you handling the *.TS files in this way you could also create a nice preview and then work something like this:
In this example I only extract the segments that need to be translated using the same rules I mentioned at the start of the article, so you only see one segment in the Editor. But then I created a custom preview using XSLT to display in realtime the “source”, “translation” and “translatorcomment” for the whole file. This could be a very nice solution giving you the full context in one view that you don’t get from the other filetypes especially if a bilingual XML filetype was created by a developer. But even like this I think it works quite nicely and you could do a better job of the preview to make it easier to read.
Using SDL Passolo
I’m adding SDL Passolo into here after Hans Pich mentioned them in the comments and after Daniel Brockmann saw this as worth mentioning because of the improved features you can have with Passolo. Now, Passolo out of the box won’t do a much better job than the solutions I have already covered, but there is a plugin available on the appstore for Passolo called SDL Passolo add-in for Qt® developed by Henk Boxma. This is a paid plugin for the full version of Passolo but if you are a translator receiving Translator Bundles for translation with the Free Edition of Passolo then you may come across this option for these types of files if your client is using Passolo for their Qt translation projects. As a translator there is no additional cost for you so you just need to open the bundle and work on the files, only the creator of the Passolo bundles incurs the cost of the plugin.
Henk describes the reasons you would use this in the manual and it does identify more complexity than I have dealt with in this article:
- Strings in TS files often do not have unique string identifiers. It is not possible to do a reliable alignment, because a different sorting order of strings in the translated file will result in misalignments.
- It is possible to define numerus forms in TS files, like for example singular, paucal and plural. The Passolo XML parser will not detect this and simply concatenate all forms to one string.
- The translator may provide length variants for a translation. For example a short and long form. Qt® will select the translation that fits best, based on the available control size.
So a few more options here that will not be handled at all with the three solutions I have discussed so far and of course you also have the Passolo benefit of preview capabilities for the UI files. I think anyone working on a large Qt project should probably consider the use of Passolo with this plugin because it may be the only way to really handle the files correctly, other than using Qt Linguist for the translation. Specialist software translation isn’t something I’ve addressed in this blog so far so perhaps it’s long overdue! The workflow (taken from the free manual provided by Henk) is as follows:
Take a look at this site if you want to learn more about handling *.TS files in Passolo.
Conclusion
I hope this article is going to be useful for anyone handling Qt Linguist files and I’d welcome any feedback from experienced users who already handle them as it would be interesting to see how this could be done better. In the meantime I hope this provides three ways to handle basic files coming from a Qt Project, one way to handle them in a more professional software localization tool, and an explanation of the elusive Qt Linguist… at least an explanation from someone who only spent an hour or so trying to find it and has no experience of how the application is used in practice. In fact if I managed to get this far I hope it’s set a good example for others and they won’t be put off by the initial barriers posed by unfamiliarity. There’s an answer for everything.
Whats about the Passolo Plugin for ts files from Qt Linguist?
Like JSON and PO files (where we also see filetypes in Studio now) most translators would prefer to use one translation tool for everything, so whilst Passolo is indeed a brilliant solution it’s not everyone’s cup of tea. But definitely good to mention this.
I have updated the article with a small section on this Hans. Thank you for prompting this.
Hmmm, but as we found out later in the very same SDL Community discussion, there _IS_ a separate Linguist installer indeed…
https://github.com/lelegard/qtlinguist-installers/releases
Thanks Evzen… I didn’t read that bug report you shared until just now. But I’m very glad to see it. Funny that the Qt guys themselves didn’t point me to this when I asked, but very good to know this. I hope they keep this updated. I’ll update the post itself to reflect your comment.
We had this issue just this week! The client had both .po and .ts files from QT Linguist. These also had translations in some of the strings. We were having difficulties with the .ts files (the .po worked great!), so we opened the .ts files in QT Linguist, saved them as .po files and they worked great! We then went into the bilinguals and locked the segments that already had translations. As mentioned above, we also try to keep the same translation tool (Studio vs Passolo) for the linguists.
Thanks Mindy… this whole discussion around *.TS files turned out to be a lot more interesting than I thought it would be at first and has been a useful learning experience for me.
Hi Paul! Now with the upcoming CU5 for Studio 2017, we will finally have embedded content rules in the XLIFF file type 🙂 🙂 🙂 So my tip to convert the *.TS files to *.PO as opposed to *.XLF will probably become obsolete.
Kind regards
Christine
Hi Christine, that’s true but I think I’ll stick with PO. I noticed a few files recently where there were additional fields in the PO and in these cases some of the content was lost in the XLIFF conversion process but retained when I used PO. I didn’t do too much troubleshooting on that but did find the PO conversion was more reliable.
BTW, in CU5, XLIFF will offer embedded content processing as well.
Thanks Patrik… see above 😉