How do I localize a Qt qmldir plugin? - qt

My app has a GUI written in Qt QML and we've successfully internationalized it using qsTr() and Qt .ts files. Now we're adding third-party plugin support via Qt's qmldir API. In the .qml files of the plugin, qsTr() works correctly only if the translation is already in the host application's .ts files. How can a third-party QML author add localized strings to their qmldir plugin?

I created a Translator class to organize and load translations. I have a QVariantMap that holds language name and file name, then when I create my Translator I have to provide the source directory since that is a requirement to load translations. My class also takes care of storing in QSettings last language used.
Now, to answer your question, you can always translate the exact same way as if it was a regular application, on your project file you will have to add something like this:
1 - List all your possible translations
TRANSLATIONS = \
translation_sp.ts \
translation_fr.ts
2 - Run lupdate to generate the actual translation files
lupdate project.pro
3 - Run lrelease
Translate with Linguist and create the actual translations. In this example, this step will generate translation_sp.qm and translation_fr.qm
4 - Deploy translations with your plugin
Once you have the .qm files deploy them with your plugin, ideally you could standardize the naming, maybe always using plugin_XX.qm
5 - Load plugin translation in application
To do this you will have to know the path to the translation file and the filename, so if your plugin is installed in the Qt default directories and you standardized the translation filenames this should be simple
qTranslator.load("plugin_XX.qm", "PATH_TO_TRANSLATION_FILE")
app->installTranslator(qtTranslator);
I simplified this in my class. Here are the header and source files of my Translator class, if you want to take a look.
And here's how you use it:
Translator translator(app.data(), "PATH_TO_TRANSLATION");
translator.addTranslation("SP", "plugin_XX.qm");
engine.rootContext()->setContextProperty("translator", &translator);
You can install multiple translators, so it will work for your application and your plugins. When I was writing my class I was not expecting different sources but you can modify it so that everytime you add a translation it will take a 2 letter code for the language, the filename and the path to it.
Hope this helps!

Related

How to automatically include Qt Linguist files into Qt resources for the CMake project?

I use CMake to build Qt project with internatiolization support. Using qt5_create_translation I can create *.ts files into the source directory and *.qm files into the build directory.
I want to reduce the number of files I should to distribute. Storing translation files :/translations/*.qm into the Qt resources is straitforward solution.
But during build process names of the resources are generated automatically and there is no native way to emplace them into the *.qrc file automatically.
How to achieve desired using, say, add_custom_command or something else?
Qt's qrc file is just xml files. Thus you can an external tool to add it.
A pure cmake solution could be:
Create a dummy resource file named #TRANS_FILE#
Add this file to your qrc file
Fetch the name of the translation file into a variable. Don't know how.
Use cmake's configure_file to replace the dummy resource name
Example:
set(TRANS_FILE ${NameOfTranslationFile})
configure_file(infile.qrc outfile.qrc #ONLY)

Custom QML Module in the Designer

Since 1 week I try to create a dynamic library which content my qml in resource file. in qmldir I declare my qml files with qrc path for not distribute my qml files to the client.
:
So when I use qrc path in my qmldir, I cannot use the auto-complementation for access to my component and I cannot access to my component form the Designer ...
But when I deploy my application my dll work fine
When I use the relative path, so without qrc://, the auto-complementation working but I cannot access to my component form the Designer ...
And when i deploy my application I NEED to deploy my qml file also of my component library
I the both case I cannot access to my component from the designer.
Maybe I make something wrong when I create my library or I forgot something ...
Any help will be appreciated for my issues...
1 : Can display my custom component in the Designer
2 : Access to auto-complementation without deploy qml
I don't know about designer, never ever used that, but in order to get auto-complete for your custom types, in addition to the qmldir file you must have a plugins.qmltypes file, which pretty much describes the structure of the components.
The good news is it can be auto-generated via:
qmlplugindump My.Module 1.0 /import/path > /import/path/my/module/plugins.qmltypes
From the looks of it, your custom types should appear in designer in their own respective tab when you import the appropriate module and have the necessary support files.

How to use a QML plugin

Can any one say the step by step method to incorporate already created plugins into a new QML based program.
I've got this plugin called qmltermwidget from git qmltermwidget github
Now i have compiled it and I can test the example program in it but I don't know how to use it in my custom application using Qt/QML
See "Creating C++ Plugins for QML".
In your case, you already have a plugin (from your previous question), but the steps involve:
Write a project file for the plugin
Create a qmldir file to describe the plugin
QML extension plugins are for either application-specific or library-like plugins.
Library plugins should limit themselves to registering types, as any manipulation of the engine's root context may cause conflicts or other issues in the library user's code.
The "Module Definition qmldir Files" is where you declare a plugin to be made available by the module.
plugin <Name> [<Path>]
<Name> is the plugin library name. This is usually not the same as the file name of the plugin binary, which is platform dependent; e.g. the library MyAppTypes would produce libMyAppTypes.so on Linux and MyAppTypes.dll on Windows.
<Path> (optional) specifies either:
an absolute path to the directory containing the plugin file, or
a relative path from the directory containing the qmldir file to the directory containing the plugin file.
By default the engine searches for the plugin library in the directory that contains the qmldir file.
The plugin search path can be queried with QQmlEngine::pluginPathList() and modified using QQmlEngine::addPluginPath().

Opening/Editing Qt Resource File (.rcc)

I want to translate a program; but its language files (.qm) are in a .rcc file.
The program is not mine, so I haven't got any .qrc file.
Before asking this question, I have searched this site about this issue; but I don't attain anything.
Is there any way to extract/decompile it?
You can take my tool RccExtended - it based on the official Qt resource compiler with additional function to decompile binary resources.
Usage example:
cd \Path\To\MyQtResources\
rcc --reverse
Decompiler will unpack all .rcc files in the current directory, generate .qrc files and make.bat file to compile resources back to the binary format.
There isn't a supported way to decompile it as far as I'm aware, but it's a binary file format that can be read and handled. There's a nodejs example of how to read the file and extract PNGs on github: https://github.com/gcochard/png-extractor. It may be possible to extend that method out for the .qm files.
However there's other issues with attempting to add more translations to a Qt application without having the code, depending on the language you're attempting to add, how the developer has exposed the other languages etc.

Add specific phrases from Qt framework to my application's translation files

Is there a way to add specific phrases from Qt frameworks's internal .ts files to my application's translation files? I only need to translate several phrases for QMessageBox and friends.
EDIT:
I also want to:
Bundle the phrases inside my application's .ts file
Prevent them from going obsolete after a routine lupdate
There's always an alternative to subclass QMessageBox, but I'd like to try a perfectionist solution first.
EDIT #2:
I've solved the problem the ugly way by shipping a .qm file with my application from the Qt distribution. I'll keep this question open in case somebody comes up with a more elegant solution.
EDITED:
For custom translation of internal Qt phrases you only need to do some steps:
Modify appropriate qt_lang.ts in translation folder inside Qt SDK directory. I strongly recommend you to use Qt linguist for this purpose.
Use lrelease utility on qt_lang.ts to produce .qm file.
Modify your code. You need to install generated translation file in your app by using QTranslator class.
Distribute your app with generated .qm. All .qm files must be arranged in special dir relative to your app binary. By default it is translations folder, but you can change this dir by using custom qt.conf.
So when you change app language you'll get needed (translated by you) phrases.
For example, if you want to achieve custom translation for russian friends you need to open qt_ru.ts in Qt Linguist, locate there QMessageBox context and translate all needed phrases. Then follow described above instruction.
In Qt you can load various ts files for your application, i would try not to extract the needed phrases but load the qt ts files along with your own translation

Resources